<!doctype html><html lang="en">
 <head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
  <title>P1673R6: P1673R6: A free function linear algebra interface based on the BLAS</title>
<style data-fill-with="stylesheet">/******************************************************************************
 *                   Style sheet for the W3C specifications                   *
 *
 * Special classes handled by this style sheet include:
 *
 * Indices
 *   - .toc for the Table of Contents (<ol class="toc">)
 *     + <span class="secno"> for the section numbers
 *   - #toc for the Table of Contents (<nav id="toc">)
 *   - ul.index for Indices (<a href="#ref">term</a><span>, in §N.M</span>)
 *   - table.index for Index Tables (e.g. for properties or elements)
 *
 * Structural Markup
 *   - table.data for general data tables
 *     -> use 'scope' attribute, <colgroup>, <thead>, and <tbody> for best results !
 *     -> use <table class='complex data'> for extra-complex tables
 *     -> use <td class='long'> for paragraph-length cell content
 *     -> use <td class='pre'> when manual line breaks/indentation would help readability
 *   - dl.switch for switch statements
 *   - ol.algorithm for algorithms (helps to visualize nesting)
 *   - .figure and .caption (HTML4) and figure and figcaption (HTML5)
 *     -> .sidefigure for right-floated figures
 *   - ins/del
 *     -> ins/del.c### for candidate and proposed changes (amendments)
 *
 * Code
 *   - pre and code
 *
 * Special Sections
 *   - .note       for informative notes             (div, p, span, aside, details)
 *   - .example    for informative examples          (div, p, pre, span)
 *   - .issue      for issues                        (div, p, span)
 *   - .advisement for loud normative statements     (div, p, strong)
 *   - .annoying-warning for spec obsoletion notices (div, aside, details)
 *   - .correction for "candidate corrections"       (div, aside, details, section)
 *   - .addition   for "candidate additions"         (div, aside, details, section)
 *   - .correction.proposed for "proposed corrections" (div, aside, details, section)
 *   - .addition.proposed   for "proposed additions"   (div, aside, details, section)
 *
 * Definition Boxes
 *   - pre.def   for WebIDL definitions
 *   - table.def for tables that define other entities (e.g. CSS properties)
 *   - dl.def    for definition lists that define other entitles (e.g. HTML elements)
 *
 * Numbering
 *   - .secno for section numbers in .toc and headings (<span class='secno'>3.2</span>)
 *   - .marker for source-inserted example/figure/issue numbers (<span class='marker'>Issue 4</span>)
 *   - ::before styled for CSS-generated issue/example/figure numbers:
 *     -> Documents wishing to use this only need to add
 *        figcaption::before,
 *        .caption::before { content: "Figure "  counter(figure) " ";  }
 *        .example::before { content: "Example " counter(example) " "; }
 *        .issue::before   { content: "Issue "   counter(issue) " ";   }
 *
 * Header Stuff (ignore, just don't conflict with these classes)
 *   - .head for the header
 *   - .copyright for the copyright
 *
 * Outdated warning for old specs
 *
 * Miscellaneous
 *   - .overlarge for things that should be as wide as possible, even if
 *     that overflows the body text area. This can be used on an item or
 *     on its container, depending on the effect desired.
 *     Note that this styling basically doesn't help at all when printing,
 *     since A4 paper isn't much wider than the max-width here.
 *     It's better to design things to fit into a narrower measure if possible.
 *
 *   - js-added ToC jump links (see fixup.js)
 *
 ******************************************************************************/

/* color variables included separately for reliability */

/******************************************************************************/
/*                                    Body                                    */
/******************************************************************************/

	html {
	}

	body {
		counter-reset: example figure issue;

		/* Layout */
		max-width: 50em;			  /* limit line length to 50em for readability   */
		margin: 0 auto;				/* center text within page                    */
		padding: 1.6em 1.5em 2em 50px; /* assume 16px font size for downlevel clients */
		padding: 1.6em 1.5em 2em calc(26px + 1.5em); /* leave space for status flag    */

		/* Typography */
		line-height: 1.5;
		font-family: sans-serif;
		widows: 2;
		orphans: 2;
		word-wrap: break-word;
		overflow-wrap: break-word;
		hyphens: auto;

		color: black;
		color: var(--text);
		background: white top left fixed no-repeat;
		background: var(--bg) top left fixed no-repeat;
		background-size: 25px auto;
	}


/******************************************************************************/
/*                         Front Matter & Navigation                          */
/******************************************************************************/

/** Header ********************************************************************/

	div.head { margin-bottom: 1em; }
	div.head hr { border-style: solid; }

	div.head h1 {
		font-weight: bold;
		margin: 0 0 .1em;
		font-size: 220%;
	}

	div.head h2 { margin-bottom: 1.5em;}

/** W3C Logo ******************************************************************/

	.head .logo {
		float: right;
		margin: 0.4rem 0 0.2rem .4rem;
	}

	.head img[src*="logos/W3C"] {
		display: block;
		border: solid #1a5e9a;
		border: solid var(--logo-bg);
		border-width: .65rem .7rem .6rem;
		border-radius: .4rem;
		background: #1a5e9a;
		background: var(--logo-bg);
		color: white;
		color: var(--logo-text);
		font-weight: bold;
	}

	.head a:hover > img[src*="logos/W3C"],
	.head a:focus > img[src*="logos/W3C"] {
		opacity: .8;
	}

	.head a:active > img[src*="logos/W3C"] {
		background: #c00;
		background: var(--logo-active-bg);
		border-color: #c00;
		border-color: var(--logo-active-bg);
	}

	/* see also additional rules in Link Styling section */

/** Copyright *****************************************************************/

	p.copyright,
	p.copyright small { font-size: small; }

/** Back to Top / ToC Toggle **************************************************/

	@media print {
		#toc-nav {
			display: none;
		}
	}
	@media not print {
		#toc-nav {
			position: fixed;
			z-index: 3;
			bottom: 0; left: 0;
			margin: 0;
			min-width: 1.33em;
			border-top-right-radius: 2rem;
			box-shadow: 0 0 2px;
			font-size: 1.5em;
		}
		#toc-nav > a {
			display: block;
			white-space: nowrap;

			height: 1.33em;
			padding: .1em 0.3em;
			margin: 0;

			box-shadow: 0 0 2px;
			border: none;
			border-top-right-radius: 1.33em;

			color: #707070;
			color: var(--tocnav-normal-text);
			background: white;
			background: var(--tocnav-normal-bg);
		}
		#toc-nav > a:hover,
		#toc-nav > a:focus {
			color: black;
			color: var(--tocnav-hover-text);
			background: #f8f8f8;
			background: var(--tocnav-hover-bg);
		}
		#toc-nav > a:active {
			color: #c00;
			color: var(--tocnav-active-text);
			background: white;
			background: var(--tocnav-active-bg);
		}

		#toc-nav > #toc-jump {
			padding-bottom: 2em;
			margin-bottom: -1.9em;
		}

		/* statusbar gets in the way on keyboard focus; remove once browsers fix */
		#toc-nav > a[href="#toc"]:not(:hover):focus:last-child {
			padding-bottom: 1.5rem;
		}

		#toc-nav:not(:hover) > a:not(:focus) > span + span {
			/* Ideally this uses :focus-within on #toc-nav */
			display: none;
		}
		#toc-nav > a > span + span {
			padding-right: 0.2em;
		}
	}

/** ToC Sidebar ***************************************************************/

	/* Floating sidebar */
	@media screen {
		body.toc-sidebar #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			max-width: 80%;
			max-width: calc(100% - 2em - 26px);
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			color: black;
			color: var(--tocsidebar-text);
			background: inherit;
			background-color: #f7f8f9;
			background-color: var(--tocsidebar-bg);
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
			box-shadow: -.1em 0 .25em var(--tocsidebar-shadow) inset;
		}
		body.toc-sidebar #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
			color: var(--tocsidebar-heading-text);
		}
		body.toc-sidebar #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	/* Hide main scroller when only the ToC is visible anyway */
	@media screen and (max-width: 28em) {
		body.toc-sidebar {
			overflow: hidden;
		}
	}

	/* Sidebar with its own space */
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			color: black;
			color: var(--tocsidebar-text);
			background: inherit;
			background-color: #f7f8f9;
			background-color: var(--tocsidebar-bg);
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
			box-shadow: -.1em 0 .25em var(--tocsidebar-shadow) inset;
		}
		body:not(.toc-inline) #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
			color: var(--tocsidebar-heading-text);
		}

		body:not(.toc-inline) {
			padding-left: 29em;
		}
		/* See also Overflow section at the bottom */

		body:not(.toc-inline) #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) {
			margin: 0 4em;
		}
	}

/******************************************************************************/
/*                                Sectioning                                  */
/******************************************************************************/

/** Headings ******************************************************************/

	h1, h2, h3, h4, h5, h6, dt {
		page-break-after: avoid;
		page-break-inside: avoid;
		font: 100% sans-serif;   /* Reset all font styling to clear out UA styles */
		font-family: inherit;	/* Inherit the font family. */
		line-height: 1.2;		/* Keep wrapped headings compact */
		hyphens: manual;		/* Hyphenated headings look weird */
	}

	h2, h3, h4, h5, h6 {
		margin-top: 3rem;
	}

	h1, h2, h3 {
		color: #005A9C;
		color: var(--heading-text);
	}

	h1 { font-size: 170%; }
	h2 { font-size: 140%; }
	h3 { font-size: 120%; }
	h4 { font-weight: bold; }
	h5 { font-style: italic; }
	h6 { font-variant: small-caps; }
	dt { font-weight: bold; }

/** Subheadings ***************************************************************/

	h1 + h2,
	#profile-and-date {
		/* #profile-and-date is a subtitle in an H2 under the H1 */
		margin-top: 0;
	}
	h2 + h3,
	h3 + h4,
	h4 + h5,
	h5 + h6 {
		margin-top: 1.2em; /* = 1 x line-height */
	}

/** Section divider ***********************************************************/

	:not(.head) > :not(.head) + hr {
		font-size: 1.5em;
		text-align: center;
		margin: 1em auto;
		height: auto;
		color: black;
		color: var(--hr-text);
		border: transparent solid 0;
		background: transparent;
	}
	:not(.head) > hr::before {
		content: "\2727\2003\2003\2727\2003\2003\2727";
	}

/******************************************************************************/
/*                            Paragraphs and Lists                            */
/******************************************************************************/

	p {
		margin: 1em 0;
	}

	dd > p:first-child,
	li > p:first-child {
		margin-top: 0;
	}

	ul, ol {
		margin-left: 0;
		padding-left: 2em;
	}

	li {
		margin: 0.25em 0 0.5em;
		padding: 0;
	}

	dl dd {
		margin: 0 0 .5em 2em;
	}

	.head dd + dd { /* compact for header */
		margin-top: -.5em;
	}

	/* Style for algorithms */
	ol.algorithm ol:not(.algorithm),
	.algorithm > ol ol:not(.algorithm) {
	border-left: 0.5em solid #DEF;
	border-left: 0.5em solid var(--algo-border);
	}

	/* Put nice boxes around each algorithm. */
	[data-algorithm]:not(.heading) {
	 padding: .5em;
	 border: thin solid #ddd;
	 border: thin solid var(--algo-border);
	 border-radius: .5em;
	 margin: .5em calc(-0.5em - 1px);
	}
	[data-algorithm]:not(.heading) > :first-child {
	 margin-top: 0;
	}
	[data-algorithm]:not(.heading) > :last-child {
	 margin-bottom: 0;
	}

	/* Style for switch/case <dl>s */
	dl.switch > dd > ol.only,
	dl.switch > dd > .only > ol {
	margin-left: 0;
	}
	dl.switch > dd > ol.algorithm,
	dl.switch > dd > .algorithm > ol {
	margin-left: -2em;
	}
	dl.switch {
	padding-left: 2em;
	}
	dl.switch > dt {
	text-indent: -1.5em;
	margin-top: 1em;
	}
	dl.switch > dt + dt {
	margin-top: 0;
	}
	dl.switch > dt::before {
	content: '\21AA';
	padding: 0 0.5em 0 0;
	display: inline-block;
	width: 1em;
	text-align: right;
	line-height: 0.5em;
	}

/** Terminology Markup ********************************************************/


/******************************************************************************/
/*                                 Inline Markup                              */
/******************************************************************************/

/** Terminology Markup ********************************************************/
	dfn   { /* Defining instance */
		font-weight: bolder;
	}
	a > i { /* Instance of term */
		font-style: normal;
	}
	dt dfn code, code.idl {
		font-size: inherit;
	}
	dfn var {
		font-style: normal;
	}

/** Change Marking ************************************************************/

	del {
		color: #aa0000;
		color: var(--del-text);
		background: transparent;
		background: var(--del-bg);
		text-decoration: line-through;
	}
	ins {
		color: #006100;
		color: var(--ins-text);
		background: transparent;
		background: var(--ins-bg);
		text-decoration: underline;
	}

	/* for amendments (candidate/proposed changes) */

	.amendment ins, .correction ins, .addition ins,
	ins[class^=c] {
		text-decoration-style: dotted;
	}
	.amendment del, .correction del, .addition del,
	del[class^=c] {
		text-decoration-style: dotted;
	}
	.amendment.proposed ins, .correction.proposed ins, .addition.proposed ins,
	ins[class^=c].proposed {
		text-decoration-style: double;
	}
	.amendment.proposed del, .correction.proposed del, .addition.proposed del,
	del[class^=c].proposed {
		text-decoration-style: double;
	}

/** Miscellaneous improvements to inline formatting ***************************/

	sup {
		vertical-align: super;
		font-size: 80%
	}

/******************************************************************************/
/*                                    Code                                    */
/******************************************************************************/

/** General monospace/pre rules ***********************************************/

	pre, code, samp {
		font-family: Menlo, Consolas, "DejaVu Sans Mono", Monaco, monospace;
		font-size: .9em;
		hyphens: none;
		text-transform: none;
		text-align: left;
		text-align: start;
		font-variant: normal;
		orphans: 3;
		widows: 3;
		page-break-before: avoid;
	}
	pre code,
	code code {
		font-size: 100%;
	}

	pre {
		margin-top: 1em;
		margin-bottom: 1em;
		overflow: auto;
	}

/** Inline Code fragments *****************************************************/

	/* Do something nice. */

/******************************************************************************/
/*                                    Links                                   */
/******************************************************************************/

/** General Hyperlinks ********************************************************/

	/* We hyperlink a lot, so make it less intrusive */
	a[href] {
		color: #034575;
		color: var(--a-normal-text);
		text-decoration: underline #707070;
		text-decoration: underline var(--a-normal-underline);
		text-decoration-skip-ink: none;
	}
	a:visited {
		color: #034575;
		color: var(--a-visited-text);
		text-decoration-color: #bbb;
		text-decoration-color: var(--a-visited-underline);
	}

	/* Indicate interaction with the link */
	a[href]:focus,
	a[href]:hover {
		text-decoration-thickness: 2px;
	}
	a[href]:active {
		color: #c00;
		color: var(--a-active-text);
		text-decoration-color: #c00;
		text-decoration-color: var(--a-active-underline);
	}

	/* Backout above styling for W3C logo */
	.head .logo,
	.head .logo a {
		border: none;
		text-decoration: none;
		background: transparent;
	}

/******************************************************************************/
/*                                    Images                                  */
/******************************************************************************/

	img {
		border-style: none;
	}

	img, svg {
		/* Intentionally not color-scheme aware. */
		background: white;
	}

	/* For autogen numbers, add
	  .caption::before, figcaption::before { content: "Figure " counter(figure) ". "; }
	*/

	figure, .figure, .sidefigure {
		page-break-inside: avoid;
		text-align: center;
		margin: 2.5em 0;
	}
	.figure img,	.sidefigure img,	figure img,
	.figure object, .sidefigure object, figure object {
		max-width: 100%;
		margin: auto;
		height: auto;
	}
	.figure pre, .sidefigure pre, figure pre {
		text-align: left;
		display: table;
		margin: 1em auto;
	}
	.figure table, figure table {
		margin: auto;
	}
	@media screen and (min-width: 20em) {
		.sidefigure {
			float: right;
			width: 50%;
			margin: 0 0 0.5em 0.5em;
		}
	}
	.caption, figcaption, caption {
		font-style: italic;
		font-size: 90%;
	}
	.caption::before, figcaption::before, figcaption > .marker {
		font-weight: bold;
	}
	.caption, figcaption {
		counter-increment: figure;
	}

	/* DL list is indented 2em, but figure inside it is not */
	dd > .figure, dd > figure { margin-left: -2em; }

/******************************************************************************/
/*                             Colored Boxes                                  */
/******************************************************************************/

	.issue, .note, .example, .assertion, .advisement, blockquote,
	.amendment, .correction, .addition {
		margin: 1em auto;
		padding: .5em;
		border: .5em;
		border-left-style: solid;
		page-break-inside: avoid;
	}
	span.issue, span.note {
		padding: .1em .5em .15em;
		border-right-style: solid;
	}

	blockquote > :first-child,
	.note  > p:first-child,
	.issue > p:first-child,
	.amendment > p:first-child,
	.correction > p:first-child,
	.addition > p:first-child {
		margin-top: 0;
	}
	blockquote > :last-child,
	.note  > p:last-child,
	.issue > p:last-child,
	.amendment > p:last-child,
	.correction > p:last-child,
	.addition > p:last-child {
		margin-bottom: 0;
	}


	.issue::before, .issue > .marker,
	.example::before, .example > .marker,
	.note::before, .note > .marker,
	details.note > summary > .marker,
	.amendment::before, .amendment > .marker,
	details.amendment > summary > .marker,
	.addition::before, .addition > .marker,
	addition.amendment > summary > .marker,
	.correction::before, .correction > .marker,
	correction.amendment > summary > .marker
	{
		text-transform: uppercase;
		padding-right: 1em;
	}

	.example::before, .example > .marker {
		display: block;
		padding-right: 0em;
	}

/** Blockquotes ***************************************************************/

	blockquote {
		border-color: silver;
		border-color: var(--blockquote-border);
		background: transparent;
		background: var(--blockquote-bg);
		color: currentcolor;
		color: var(--blockquote-text);
	}

/** Open issue ****************************************************************/

	.issue {
		border-color: #e05252;
		border-color: var(--issue-border);
		background: #fbe9e9;
		background: var(--issue-bg);
		color: black;
		color: var(--issue-text);
		counter-increment: issue;
		overflow: auto;
	}
	.issue::before, .issue > .marker {
		color: #831616;
		color: var(--issueheading-text);
	}
	/* Add .issue::before { content: "Issue " counter(issue) " "; } for autogen numbers,
	  or use class="marker" to mark up the issue number in source. */

/** Example *******************************************************************/

	.example {
		border-color: #e0cb52;
		border-color: var(--example-border);
		background: #fcfaee;
		background: var(--example-bg);
		color: black;
		color: var(--example-text);
		counter-increment: example;
		overflow: auto;
		clear: both;
	}
	.example::before, .example > .marker {
		color: #574b0f;
		color: var(--exampleheading-text);
	}
	/* Add .example::before { content: "Example " counter(example) " "; } for autogen numbers,
	  or use class="marker" to mark up the example number in source. */

/** Non-normative Note ********************************************************/

	.note {
		border-color: #52e052;
		border-color: var(--note-border);
		background: #e9fbe9;
		background: var(--note-bg);
		color: black;
		color: var(--note-text);
		overflow: auto;
	}

	.note::before, .note > .marker,
	details.note > summary {
		color: hsl(120, 70%, 30%);
		color: var(--noteheading-text);
	}
	/* Add .note::before { content: "Note "; } for autogen label,
	  or use class="marker" to mark up the label in source. */

	details.note[open] > summary {
		border-bottom: 1px silver solid;
		border-bottom: 1px var(--notesummary-underline) solid;
	}

/** Assertion Box *************************************************************/
	/*  for assertions in algorithms */

	.assertion {
		border-color: #AAA;
		border-color: var(--assertion-border);
		background: #EEE;
		background: var(--assertion-bg);
		color: black;
		color: var(--assertion-text);
	}

/** Advisement Box ************************************************************/
	/*  for attention-grabbing normative statements */

	.advisement {
		border-color: orange;
		border-color: var(--advisement-border);
		border-style: none solid;
		background: #fec;
		background: var(--advisement-bg);
		color: black;
		color: var(--advisement-text);
	}
	strong.advisement {
		display: block;
		text-align: center;
	}
	.advisement::before, .advisement > .marker {
		color: #b35f00;
		color: var(--advisementheading-text);
	}

/** Amendment Box *************************************************************/

	.amendment, .correction, .addition {
		border-color: #330099;
		border-color: var(--amendment-border);
		background: #F5F0FF;
		background: var(--amendment-bg);
		color: black;
		color: var(--amendment-text);
	}
	.amendment.proposed, .correction.proposed, .addition.proposed {
		border-style: solid;
		border-block-width: 0.25em;
	}
	.amendment::before, .amendment > .marker,
	details.amendment > summary::before, details.amendment > summary > .marker,
	.correction::before, .correction > .marker,
	details.correction > summary::before, details.correction > summary > .marker,
	.addition::before, .addition > .marker,
	details.addition > summary::before, details.addition > summary > .marker {
		color: #220066;
		color: var(--amendmentheading-text);
	}
	.amendment.proposed::before, .amendment.proposed > .marker,
	details.amendment.proposed > summary::before, details.amendment.proposed > summary > .marker,
	.correction.proposed::before, .correction.proposed > .marker,
	details.correction.proposed > summary::before, details.correction.proposed > summary > .marker,
	.addition.proposed::before, .addition.proposed > .marker,
	details.addition.proposed > summary::before, details.addition.proposed > summary > .marker {
		font-weight: bold;
	}

/** Spec Obsoletion Notice ****************************************************/
	/* obnoxious obsoletion notice for older/abandoned specs. */

	details {
		display: block;
	}
	summary {
		font-weight: bolder;
	}

	.annoying-warning:not(details),
	details.annoying-warning:not([open]) > summary,
	details.annoying-warning[open] {
		background: hsla(40,100%,50%,0.95);
		background: var(--warning-bg);
		color: black;
		color: var(--warning-text);
		padding: .75em 1em;
		border: red;
		border: var(--warning-border);
		border-style: solid none;
		box-shadow: 0 2px 8px black;
		text-align: center;
	}
	.annoying-warning :last-child {
		margin-bottom: 0;
	}

@media not print {
	details.annoying-warning[open] {
		position: fixed;
		left: 0;
		right: 0;
		bottom: 2em;
		z-index: 1000;
	}
}

	details.annoying-warning:not([open]) > summary {
		text-align: center;
	}

/** Entity Definition Boxes ***************************************************/

	.def {
		padding: .5em 1em;
		background: #def;
		background: var(--def-bg);
		margin: 1.2em 0;
		border-left: 0.5em solid #8ccbf2;
		border-left: 0.5em solid var(--def-border);
		color: black;
		color: var(--def-text);
	}

/******************************************************************************/
/*                                    Tables                                  */
/******************************************************************************/

	th, td {
		text-align: left;
		text-align: start;
	}

/** Property/Descriptor Definition Tables *************************************/

	table.def {
		/* inherits .def box styling, see above */
		width: 100%;
		border-spacing: 0;
	}

	table.def td,
	table.def th {
		padding: 0.5em;
		vertical-align: baseline;
		border-bottom: 1px solid #bbd7e9;
		border-bottom: 1px solid var(--defrow-border);
	}

	table.def > tbody > tr:last-child th,
	table.def > tbody > tr:last-child td {
		border-bottom: 0;
	}

	table.def th {
		font-style: italic;
		font-weight: normal;
		padding-left: 1em;
		width: 3em;
	}

	/* For when values are extra-complex and need formatting for readability */
	table td.pre {
		white-space: pre-wrap;
	}

	/* A footnote at the bottom of a def table */
	table.def td.footnote {
		padding-top: 0.6em;
	}
	table.def td.footnote::before {
		content: " ";
		display: block;
		height: 0.6em;
		width: 4em;
		border-top: thin solid;
	}

/** Data tables (and properly marked-up index tables) *************************/
	/*
		<table class="data"> highlights structural relationships in a table
		when correct markup is used (e.g. thead/tbody, th vs. td, scope attribute)

		Use class="complex data" for particularly complicated tables --
		(This will draw more lines: busier, but clearer.)

		Use class="long" on table cells with paragraph-like contents
		(This will adjust text alignment accordingly.)
		Alternately use class="longlastcol" on tables, to have the last column assume "long".
	*/

	table {
		word-wrap: normal;
		overflow-wrap: normal;
		hyphens: manual;
	}

	table.data,
	table.index {
		margin: 1em auto;
		border-collapse: collapse;
		border: hidden;
		width: 100%;
	}
	table.data caption,
	table.index caption {
		max-width: 50em;
		margin: 0 auto 1em;
	}

	table.data td,  table.data th,
	table.index td, table.index th {
		padding: 0.5em 1em;
		border-width: 1px;
		border-color: silver;
		border-color: var(--datacell-border);
		border-top-style: solid;
	}

	table.data thead td:empty {
		padding: 0;
		border: 0;
	}

	table.data  thead,
	table.index thead,
	table.data  tbody,
	table.index tbody {
		border-bottom: 2px solid;
	}

	table.data colgroup,
	table.index colgroup {
		border-left: 2px solid;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		border-right: 2px solid;
		border-top: 1px solid silver;
		border-top: 1px solid var(--datacell-border);
		padding-right: 1em;
	}

	table.data th[colspan],
	table.data td[colspan] {
		text-align: center;
	}

	table.complex.data th,
	table.complex.data td {
		border: 1px solid silver;
		border: 1px solid var(--datacell-border);
		text-align: center;
	}

	table.data.longlastcol td:last-child,
	table.data td.long {
		vertical-align: baseline;
		text-align: left;
	}

	table.data img {
		vertical-align: middle;
	}


/*
Alternate table alignment rules

	table.data,
	table.index {
		text-align: center;
	}

	table.data  thead th[scope="row"],
	table.index thead th[scope="row"] {
		text-align: right;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		text-align: right;
	}

Possible extra rowspan handling

	table.data  tbody th[rowspan]:not([rowspan='1']),
	table.index tbody th[rowspan]:not([rowspan='1']),
	table.data  tbody td[rowspan]:not([rowspan='1']),
	table.index tbody td[rowspan]:not([rowspan='1']) {
		border-left: 1px solid silver;
	}

	table.data  tbody th[rowspan]:first-child,
	table.index tbody th[rowspan]:first-child,
	table.data  tbody td[rowspan]:first-child,
	table.index tbody td[rowspan]:first-child{
		border-left: 0;
		border-right: 1px solid silver;
	}
*/

/******************************************************************************/
/*                                  Indices                                   */
/******************************************************************************/


/** Table of Contents *********************************************************/

	.toc a {
		/* More spacing; use padding to make it part of the click target. */
		padding: 0.1rem 1px 0;
		/* Larger, more consistently-sized click target */
		display: block;
		/* Switch to using border-bottom for underlines */
		text-decoration: none;
		border-bottom: 1px solid;
		/* Reverse color scheme */
		color: black;
		color: var(--toclink-text);
		border-color: #3980b5;
		border-color: var(--toclink-underline);
	}
	.toc a:visited {
		color: black;
		color: var(--toclink-visited-text);
		border-color: #054572;
		border-color: var(--toclink-visited-underline);
	}
	.toc a:focus,
	.toc a:hover {
		background: rgba(75%, 75%, 75%, .25);
		background: var(--a-hover-bg);
		border-bottom-width: 3px;
		margin-bottom: -2px;
	}
	.toc a:not(:focus):not(:hover) {
		/* Allow colors to cascade through from link styling */
		border-bottom-color: transparent;
	}

	.toc, .toc ol, .toc ul, .toc li {
		list-style: none; /* Numbers must be inlined into source */
		/* because generated content isn't search/selectable and markers can't do multilevel yet */
		margin:  0;
		padding: 0;
	}
	.toc {
		line-height: 1.1em;
	}

	/* ToC not indented until third level, but font style & margins show hierarchy */
	.toc > li			{ font-weight: bold;   }
	.toc > li li		 { font-weight: normal; }
	.toc > li li li	  { font-size:   95%;	}
	.toc > li li li li	{ font-size:   90%;	}
	.toc > li li li li li { font-size:   85%;	}

	/* @supports not (display:grid) { */
		.toc > li			{ margin: 1.5rem 0;	}
		.toc > li li		 { margin: 0.3rem 0;	}
		.toc > li li li	  { margin-left: 2rem;   }

		/* Section numbers in a column of their own */
		.toc .secno {
			float: left;
			width: 4rem;
			white-space: nowrap;
		}
		.toc > li li li li .secno { font-size: 85%; }
		.toc > li li li li li .secno { font-size: 100%; }

		.toc li {
			clear: both;
		}

		:not(li) > .toc			 { margin-left:  5rem; }
		.toc .secno				 { margin-left: -5rem; }
		.toc > li li li .secno	  { margin-left: -7rem; }
		.toc > li li li li .secno	{ margin-left: -9rem; }
		.toc > li li li li li .secno { margin-left: -11rem; }

		/* Tighten up indentation in narrow ToCs */
		@media (max-width: 30em) {
			:not(li) > .toc			 { margin-left:  4rem; }
			.toc .secno				 { margin-left: -4rem; }
			.toc > li li li			 { margin-left:  1rem; }
			.toc > li li li .secno	  { margin-left: -5rem; }
			.toc > li li li li .secno	{ margin-left: -6rem; }
			.toc > li li li li li .secno { margin-left: -7rem; }
		}
		/* Loosen it on wide screens */
		@media screen and (min-width: 78em) {
			body:not(.toc-inline) :not(li) > .toc			 { margin-left:  4rem; }
			body:not(.toc-inline) .toc .secno				 { margin-left: -4rem; }
			body:not(.toc-inline) .toc > li li li			 { margin-left:  1rem; }
			body:not(.toc-inline) .toc > li li li .secno	  { margin-left: -5rem; }
			body:not(.toc-inline) .toc > li li li li .secno	{ margin-left: -6rem; }
			body:not(.toc-inline) .toc > li li li li li .secno { margin-left: -7rem; }
	}
	/* } */

	@supports (display:grid) and (display:contents) {
		/* Use #toc over .toc to override non-@supports rules. */
		#toc {
			display: grid;
			align-content: start;
			grid-template-columns: auto 1fr;
			grid-column-gap: 1rem;
			column-gap: 1rem;
			grid-row-gap: .6rem;
			row-gap: .6rem;
		}
		#toc h2 {
			grid-column: 1 / -1;
			margin-bottom: 0;
		}
		#toc ol,
		#toc li,
		#toc a {
			display: contents;
			/* Switch <a> to subgrid when supported */
		}
		#toc span {
			margin: 0;
		}
		#toc > .toc > li > a > span {
			/* The spans of the top-level list,
			  comprising the first items of each top-level section. */
			margin-top: 1.1rem;
		}
		#toc#toc .secno { /* Ugh, need more specificity to override base.css */
			grid-column: 1;
			width: auto;
			margin-left: 0;
		}
		#toc .content {
			grid-column: 2;
			width: auto;
			margin-right: 1rem;
		}
		#toc .content:hover,
		#toc .content:focus {
			background: rgba(75%, 75%, 75%, .25);
			background: var(--a-hover-bg);
			border-bottom: 3px solid #054572;
			border-bottom: 3px solid var(--toclink-underline);
			margin-bottom: -3px;
		}
		#toc li li li .content {
			margin-left: 1rem;
		}
		#toc li li li li .content {
			margin-left: 2rem;
		}
	}


/** Index *********************************************************************/

	/* Index Lists: Layout */
	ul.index	  { margin-left: 0; columns: 15em; text-indent: 1em hanging; }
	ul.index li	{ margin-left: 0; list-style: none; break-inside: avoid; }
	ul.index li li { margin-left: 1em; }
	ul.index dl	{ margin-top: 0; }
	ul.index dt	{ margin: .2em 0 .2em 20px;}
	ul.index dd	{ margin: .2em 0 .2em 40px;}
	/* Index Lists: Typography */
	ul.index ul,
	ul.index dl { font-size: smaller; }
	@media not print {
		ul.index li span:not(.dfn-paneled) {
			white-space: nowrap;
			color: transparent; }
		ul.index li a:hover + span,
		ul.index li a:focus + span {
			color: #707070;
			color: var(--indexinfo-text);
		}
	}

/** Index Tables *****************************************************/
	/* See also the data table styling section, which this effectively subclasses */

	table.index {
		font-size: small;
		border-collapse: collapse;
		border-spacing: 0;
		text-align: left;
		margin: 1em 0;
	}

	table.index td,
	table.index th {
		padding: 0.4em;
	}

	table.index tr:hover td:not([rowspan]),
	table.index tr:hover th:not([rowspan]) {
		color: black;
		color: var(--indextable-hover-text);
		background: #f7f8f9;
		background: var(--indextable-hover-bg);
	}

	/* The link in the first column in the property table (formerly a TD) */
	table.index th:first-child a {
		font-weight: bold;
	}

/** Outdated warning **********************************************************/

.outdated-spec {
	color: black;
	color: var(--outdatedspec-text);
	background-color: rgba(0,0,0,0.5);
	background-color: var(--outdatedspec-bg);
}

.outdated-warning {
	position: fixed;
	bottom: 50%;
	left: 0;
	right: 0;
	margin: 0 auto;
	width: 50%;
	background: maroon;
	background: var(--outdated-bg);
	color: white;
	color: var(--outdated-text);
	border-radius: 1em;
	box-shadow: 0 0 1em red;
	box-shadow: 0 0 1em var(--outdated-shadow);
	padding: 2em;
	text-align: center;
	z-index: 2;
}

.outdated-warning a {
	color: currentcolor;
	background: transparent;
}

.edited-rec-warning {
	background: darkorange;
	background: var(--editedrec-bg);
	box-shadow: 0 0 1em;
}

.outdated-warning button {
	color: var(--outdated-text);
	border-radius: 1em;
	box-shadow: 0 0 1em red;
	box-shadow: 0 0 1em var(--outdated-shadow);
	padding: 2em;
	text-align: center;
	z-index: 2;
}

.outdated-warning a {
	color: currentcolor;
	background: transparent;
}

.edited-rec-warning {
	background: darkorange;
	background: var(--editedrec-bg);
	box-shadow: 0 0 1em;
}

.outdated-warning button {
	position: absolute;
	top: 0;
	right:0;
	margin: 0;
	border: 0;
	padding: 0.25em 0.5em;
	background: transparent;
	color: white;
	color: var(--outdated-text);
	font:1em sans-serif;
	text-align:center;
}

.outdated-warning span {
	display: block;
}

.outdated-collapsed {
	bottom: 0;
	border-radius: 0;
	width: 100%;
	padding: 0;
}

/******************************************************************************/
/*                                    Print                                   */
/******************************************************************************/

	@media print {
		/* Pages have their own margins. */
		html {
			margin: 0;
		}
		/* Serif for print. */
		body {
			font-family: serif;
		}

		.outdated-warning {
			position: absolute;
			border-style: solid;
			border-color: red;
		}

		.outdated-warning input {
			display: none;
		}
	}
	@page {
		margin: 1.5cm 1.1cm;
	}



/******************************************************************************/
/*                             Overflow Control                               */
/******************************************************************************/

	.figure .caption, .sidefigure .caption, figcaption {
		/* in case figure is overlarge, limit caption to 50em */
		max-width: 50rem;
		margin-left: auto;
		margin-right: auto;
	}
	.overlarge {
		/* Magic to create good item positioning:
		  "content column" is 50ems wide at max; less on smaller screens.
		  Extra space (after ToC + content) is empty on the right.

		  1. When item < content column, centers item in column.
		  2. When content < item < available, left-aligns.
		  3. When item > available, fills available + scroll bar.
		*/
		display: grid;
		grid-template-columns: minmax(0, 50em);
	}
	.overlarge > table {
		/* limit preferred width of table */
		max-width: 50em;
		margin-left: auto;
		margin-right: auto;
	}

	@media (min-width: 55em) {
		.overlarge {
			margin-right: calc(13px + 26.5rem - 50vw);
			max-width: none;
		}
	}
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) .overlarge {
			/* 30.5em body padding 50em content area */
			margin-right: calc(40em - 50vw) !important;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) .overlarge {
			/* 4em html margin 30.5em body padding 50em content area */
			margin-right: calc(84.5em - 100vw) !important;
		}
	}

	@media not print {
		.overlarge {
			overflow-x: auto;
			/* See Lea Verou's explanation background-attachment:
			* http://lea.verou.me/2012/04/background-attachment-local/
			*
			background: top left  / 4em 100% linear-gradient(to right,  #ffffff, rgba(255, 255, 255, 0)) local,
						top right / 4em 100% linear-gradient(to left, #ffffff, rgba(255, 255, 255, 0)) local,
						top left  / 1em 100% linear-gradient(to right,  #c3c3c5, rgba(195, 195, 197, 0)) scroll,
						top right / 1em 100% linear-gradient(to left, #c3c3c5, rgba(195, 195, 197, 0)) scroll,
						white;
			background-repeat: no-repeat;
			*/
		}
	}
</style>
<style type="text/css">
    table, th, td {
      border: 1px solid black;
      border-collapse: collapse;
      vertical-align: top;
    }
    th, td {
      border-left: none;
      border-right: none;
      padding: 0px 10px;
    }
    th {
      text-align: center;
    }

    del { background: #fcc; color: #000; text-decoration: line-through; }
    ins { background: #cfc; color: #000; }
    blockquote .highlight:not(.idl) { background: initial; margin: initial; padding: 0.5em }
    blockquote ul { background: inherit; }
    blockquote code.highlight:not(.idl) { padding: initial; }
    blockquote c-[a] { color: inherit; } /* Keyword.Declaration */
    blockquote c-[b] { color: inherit; } /* Keyword.Type */
    blockquote c-[c] { color: inherit; } /* Comment */
    blockquote c-[d] { color: inherit; } /* Comment.Multiline */
    blockquote c-[e] { color: inherit; } /* Name.Attribute */
    blockquote c-[f] { color: inherit; } /* Name.Tag */
    blockquote c-[g] { color: inherit; } /* Name.Variable */
    blockquote c-[k] { color: inherit; } /* Keyword */
    blockquote c-[l] { color: inherit; } /* Literal */
    blockquote c-[m] { color: inherit; } /* Literal.Number */
    blockquote c-[n] { color: inherit; } /* Name */
    blockquote c-[o] { color: inherit; } /* Operator */
    blockquote c-[p] { color: inherit; } /* Punctuation */
    blockquote c-[s] { color: inherit; } /* Literal.String */
    blockquote c-[t] { color: inherit; } /* Literal.String.Single */
    blockquote c-[u] { color: inherit; } /* Literal.String.Double */
    blockquote c-[cp] { color: inherit; } /* Comment.Preproc */
    blockquote c-[c1] { color: inherit; } /* Comment.Single */
    blockquote c-[cs] { color: inherit; } /* Comment.Special */
    blockquote c-[kc] { color: inherit; } /* Keyword.Constant */
    blockquote c-[kn] { color: inherit; } /* Keyword.Namespace */
    blockquote c-[kp] { color: inherit; } /* Keyword.Pseudo */
    blockquote c-[kr] { color: inherit; } /* Keyword.Reserved */
    blockquote c-[ld] { color: inherit; } /* Literal.Date */
    blockquote c-[nc] { color: inherit; } /* Name.Class */
    blockquote c-[no] { color: inherit; } /* Name.Constant */
    blockquote c-[nd] { color: inherit; } /* Name.Decorator */
    blockquote c-[ni] { color: inherit; } /* Name.Entity */
    blockquote c-[ne] { color: inherit; } /* Name.Exception */
    blockquote c-[nf] { color: inherit; } /* Name.Function */
    blockquote c-[nl] { color: inherit; } /* Name.Label */
    blockquote c-[nn] { color: inherit; } /* Name.Namespace */
    blockquote c-[py] { color: inherit; } /* Name.Property */
    blockquote c-[ow] { color: inherit; } /* Operator.Word */
    blockquote c-[mb] { color: inherit; } /* Literal.Number.Bin */
    blockquote c-[mf] { color: inherit; } /* Literal.Number.Float */
    blockquote c-[mh] { color: inherit; } /* Literal.Number.Hex */
    blockquote c-[mi] { color: inherit; } /* Literal.Number.Integer */
    blockquote c-[mo] { color: inherit; } /* Literal.Number.Oct */
    blockquote c-[sb] { color: inherit; } /* Literal.String.Backtick */
    blockquote c-[sc] { color: inherit; } /* Literal.String.Char */
    blockquote c-[sd] { color: inherit; } /* Literal.String.Doc */
    blockquote c-[se] { color: inherit; } /* Literal.String.Escape */
    blockquote c-[sh] { color: inherit; } /* Literal.String.Heredoc */
    blockquote c-[si] { color: inherit; } /* Literal.String.Interpol */
    blockquote c-[sx] { color: inherit; } /* Literal.String.Other */
    blockquote c-[sr] { color: inherit; } /* Literal.String.Regex */
    blockquote c-[ss] { color: inherit; } /* Literal.String.Symbol */
    blockquote c-[vc] { color: inherit; } /* Name.Variable.Class */
    blockquote c-[vg] { color: inherit; } /* Name.Variable.Global */
    blockquote c-[vi] { color: inherit; } /* Name.Variable.Instance */
    blockquote c-[il] { color: inherit; } /* Literal.Number.Integer.Long */
  </style>
  <meta content="Bikeshed version 3d6a6fcbb, updated Wed Jun 16 16:19:39 2021 -0700" name="generator">
  <link href="https://github.com/ORNL/cpp-proposals-pub/blob/master/D1673/P1673.bs" rel="canonical">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
  <meta content="f13bd4aed8f5db7cb1b7dfe4436022e725c7b342" name="document-revision">
<style>/* style-autolinks */

.css.css, .property.property, .descriptor.descriptor {
    color: var(--a-normal-text);
    font-size: inherit;
    font-family: inherit;
}
.css::before, .property::before, .descriptor::before {
    content: "‘";
}
.css::after, .property::after, .descriptor::after {
    content: "’";
}
.property, .descriptor {
    /* Don't wrap property and descriptor names */
    white-space: nowrap;
}
.type { /* CSS value <type> */
    font-style: italic;
}
pre .property::before, pre .property::after {
    content: "";
}
[data-link-type="property"]::before,
[data-link-type="propdesc"]::before,
[data-link-type="descriptor"]::before,
[data-link-type="value"]::before,
[data-link-type="function"]::before,
[data-link-type="at-rule"]::before,
[data-link-type="selector"]::before,
[data-link-type="maybe"]::before {
    content: "‘";
}
[data-link-type="property"]::after,
[data-link-type="propdesc"]::after,
[data-link-type="descriptor"]::after,
[data-link-type="value"]::after,
[data-link-type="function"]::after,
[data-link-type="at-rule"]::after,
[data-link-type="selector"]::after,
[data-link-type="maybe"]::after {
    content: "’";
}

[data-link-type].production::before,
[data-link-type].production::after,
.prod [data-link-type]::before,
.prod [data-link-type]::after {
    content: "";
}

[data-link-type=element],
[data-link-type=element-attr] {
    font-family: Menlo, Consolas, "DejaVu Sans Mono", monospace;
    font-size: .9em;
}
[data-link-type=element]::before { content: "<" }
[data-link-type=element]::after  { content: ">" }

[data-link-type=biblio] {
    white-space: pre;
}</style>
<style>/* style-colors */

/* Any --*-text not paired with a --*-bg is assumed to have a transparent bg */
:root {
    color-scheme: light dark;

    --text: black;
    --bg: white;

    --unofficial-watermark: url(https://www.w3.org/StyleSheets/TR/2016/logos/UD-watermark);

    --logo-bg: #1a5e9a;
    --logo-active-bg: #c00;
    --logo-text: white;

    --tocnav-normal-text: #707070;
    --tocnav-normal-bg: var(--bg);
    --tocnav-hover-text: var(--tocnav-normal-text);
    --tocnav-hover-bg: #f8f8f8;
    --tocnav-active-text: #c00;
    --tocnav-active-bg: var(--tocnav-normal-bg);

    --tocsidebar-text: var(--text);
    --tocsidebar-bg: #f7f8f9;
    --tocsidebar-shadow: rgba(0,0,0,.1);
    --tocsidebar-heading-text: hsla(203,20%,40%,.7);

    --toclink-text: var(--text);
    --toclink-underline: #3980b5;
    --toclink-visited-text: var(--toclink-text);
    --toclink-visited-underline: #054572;

    --heading-text: #005a9c;

    --hr-text: var(--text);

    --algo-border: #def;

    --del-text: red;
    --del-bg: transparent;
    --ins-text: #080;
    --ins-bg: transparent;

    --a-normal-text: #034575;
    --a-normal-underline: #bbb;
    --a-visited-text: var(--a-normal-text);
    --a-visited-underline: #707070;
    --a-hover-bg: rgba(75%, 75%, 75%, .25);
    --a-active-text: #c00;
    --a-active-underline: #c00;

    --blockquote-border: silver;
    --blockquote-bg: transparent;
    --blockquote-text: currentcolor;

    --issue-border: #e05252;
    --issue-bg: #fbe9e9;
    --issue-text: var(--text);
    --issueheading-text: #831616;

    --example-border: #e0cb52;
    --example-bg: #fcfaee;
    --example-text: var(--text);
    --exampleheading-text: #574b0f;

    --note-border: #52e052;
    --note-bg: #e9fbe9;
    --note-text: var(--text);
    --noteheading-text: hsl(120, 70%, 30%);
    --notesummary-underline: silver;

    --assertion-border: #aaa;
    --assertion-bg: #eee;
    --assertion-text: black;

    --advisement-border: orange;
    --advisement-bg: #fec;
    --advisement-text: var(--text);
    --advisementheading-text: #b35f00;

    --warning-border: red;
    --warning-bg: hsla(40,100%,50%,0.95);
    --warning-text: var(--text);

    --amendment-border: #330099;
    --amendment-bg: #F5F0FF;
    --amendment-text: var(--text);
    --amendmentheading-text: #220066;

    --def-border: #8ccbf2;
    --def-bg: #def;
    --def-text: var(--text);
    --defrow-border: #bbd7e9;

    --datacell-border: silver;

    --indexinfo-text: #707070;

    --indextable-hover-text: black;
    --indextable-hover-bg: #f7f8f9;

    --outdatedspec-bg: rgba(0, 0, 0, .5);
    --outdatedspec-text: black;
    --outdated-bg: maroon;
    --outdated-text: white;
    --outdated-shadow: red;

    --editedrec-bg: darkorange;
}</style>
<style>/* style-counters */

body {
    counter-reset: example figure issue;
}
.issue {
    counter-increment: issue;
}
.issue:not(.no-marker)::before {
    content: "Issue " counter(issue);
}

.example {
    counter-increment: example;
}
.example:not(.no-marker)::before {
    content: "Example " counter(example);
}
.invalid.example:not(.no-marker)::before,
.illegal.example:not(.no-marker)::before {
    content: "Invalid Example" counter(example);
}

figcaption {
    counter-increment: figure;
}
figcaption:not(.no-marker)::before {
    content: "Figure " counter(figure) " ";
}</style>
<style>/* style-md-lists */

/* This is a weird hack for me not yet following the commonmark spec
   regarding paragraph and lists. */
[data-md] > :first-child {
    margin-top: 0;
}
[data-md] > :last-child {
    margin-bottom: 0;
}</style>
<style>/* style-selflinks */

:root {
    --selflink-text: white;
    --selflink-bg: gray;
    --selflink-hover-text: black;
}
.heading, .issue, .note, .example, li, dt {
    position: relative;
}
a.self-link {
    position: absolute;
    top: 0;
    left: calc(-1 * (3.5rem - 26px));
    width: calc(3.5rem - 26px);
    height: 2em;
    text-align: center;
    border: none;
    transition: opacity .2s;
    opacity: .5;
}
a.self-link:hover {
    opacity: 1;
}
.heading > a.self-link {
    font-size: 83%;
}
li > a.self-link {
    left: calc(-1 * (3.5rem - 26px) - 2em);
}
dfn > a.self-link {
    top: auto;
    left: auto;
    opacity: 0;
    width: 1.5em;
    height: 1.5em;
    background: var(--selflink-bg);
    color: var(--selflink-text);
    font-style: normal;
    transition: opacity .2s, background-color .2s, color .2s;
}
dfn:hover > a.self-link {
    opacity: 1;
}
dfn > a.self-link:hover {
    color: var(--selflink-hover-text);
}

a.self-link::before            { content: "¶"; }
.heading > a.self-link::before { content: "§"; }
dfn > a.self-link::before      { content: "#"; }
</style>
<style>/* style-syntax-highlighting */

code.highlight { padding: .1em; border-radius: .3em; }
pre.highlight, pre > code.highlight { display: block; padding: 1em; margin: .5em 0; overflow: auto; border-radius: 0; }

.highlight:not(.idl) { background: rgba(0, 0, 0, .03); }
c-[a] { color: #990055 } /* Keyword.Declaration */
c-[b] { color: #990055 } /* Keyword.Type */
c-[c] { color: #708090 } /* Comment */
c-[d] { color: #708090 } /* Comment.Multiline */
c-[e] { color: #0077aa } /* Name.Attribute */
c-[f] { color: #669900 } /* Name.Tag */
c-[g] { color: #222222 } /* Name.Variable */
c-[k] { color: #990055 } /* Keyword */
c-[l] { color: #000000 } /* Literal */
c-[m] { color: #000000 } /* Literal.Number */
c-[n] { color: #0077aa } /* Name */
c-[o] { color: #999999 } /* Operator */
c-[p] { color: #999999 } /* Punctuation */
c-[s] { color: #a67f59 } /* Literal.String */
c-[t] { color: #a67f59 } /* Literal.String.Single */
c-[u] { color: #a67f59 } /* Literal.String.Double */
c-[cp] { color: #708090 } /* Comment.Preproc */
c-[c1] { color: #708090 } /* Comment.Single */
c-[cs] { color: #708090 } /* Comment.Special */
c-[kc] { color: #990055 } /* Keyword.Constant */
c-[kn] { color: #990055 } /* Keyword.Namespace */
c-[kp] { color: #990055 } /* Keyword.Pseudo */
c-[kr] { color: #990055 } /* Keyword.Reserved */
c-[ld] { color: #000000 } /* Literal.Date */
c-[nc] { color: #0077aa } /* Name.Class */
c-[no] { color: #0077aa } /* Name.Constant */
c-[nd] { color: #0077aa } /* Name.Decorator */
c-[ni] { color: #0077aa } /* Name.Entity */
c-[ne] { color: #0077aa } /* Name.Exception */
c-[nf] { color: #0077aa } /* Name.Function */
c-[nl] { color: #0077aa } /* Name.Label */
c-[nn] { color: #0077aa } /* Name.Namespace */
c-[py] { color: #0077aa } /* Name.Property */
c-[ow] { color: #999999 } /* Operator.Word */
c-[mb] { color: #000000 } /* Literal.Number.Bin */
c-[mf] { color: #000000 } /* Literal.Number.Float */
c-[mh] { color: #000000 } /* Literal.Number.Hex */
c-[mi] { color: #000000 } /* Literal.Number.Integer */
c-[mo] { color: #000000 } /* Literal.Number.Oct */
c-[sb] { color: #a67f59 } /* Literal.String.Backtick */
c-[sc] { color: #a67f59 } /* Literal.String.Char */
c-[sd] { color: #a67f59 } /* Literal.String.Doc */
c-[se] { color: #a67f59 } /* Literal.String.Escape */
c-[sh] { color: #a67f59 } /* Literal.String.Heredoc */
c-[si] { color: #a67f59 } /* Literal.String.Interpol */
c-[sx] { color: #a67f59 } /* Literal.String.Other */
c-[sr] { color: #a67f59 } /* Literal.String.Regex */
c-[ss] { color: #a67f59 } /* Literal.String.Symbol */
c-[vc] { color: #0077aa } /* Name.Variable.Class */
c-[vg] { color: #0077aa } /* Name.Variable.Global */
c-[vi] { color: #0077aa } /* Name.Variable.Instance */
c-[il] { color: #000000 } /* Literal.Number.Integer.Long */
</style>
<style>/* style-darkmode */

@media (prefers-color-scheme: dark) {
    :root {
        --text: #ddd;
        --bg: black;

        --unofficial-watermark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400'%3E%3Cg fill='%23100808' transform='translate(200 200) rotate(-45) translate(-200 -200)' stroke='%23100808' stroke-width='3'%3E%3Ctext x='50%25' y='220' style='font: bold 70px sans-serif; text-anchor: middle; letter-spacing: 6px;'%3EUNOFFICIAL%3C/text%3E%3Ctext x='50%25' y='305' style='font: bold 70px sans-serif; text-anchor: middle; letter-spacing: 6px;'%3EDRAFT%3C/text%3E%3C/g%3E%3C/svg%3E");

        --logo-bg: #1a5e9a;
        --logo-active-bg: #c00;
        --logo-text: white;

        --tocnav-normal-text: #999;
        --tocnav-normal-bg: var(--bg);
        --tocnav-hover-text: var(--tocnav-normal-text);
        --tocnav-hover-bg: #080808;
        --tocnav-active-text: #f44;
        --tocnav-active-bg: var(--tocnav-normal-bg);

        --tocsidebar-text: var(--text);
        --tocsidebar-bg: #080808;
        --tocsidebar-shadow: rgba(255,255,255,.1);
        --tocsidebar-heading-text: hsla(203,20%,40%,.7);

        --toclink-text: var(--text);
        --toclink-underline: #6af;
        --toclink-visited-text: var(--toclink-text);
        --toclink-visited-underline: #054572;

        --heading-text: #8af;

        --hr-text: var(--text);

        --algo-border: #456;

        --del-text: #f44;
        --del-bg: transparent;
        --ins-text: #4a4;
        --ins-bg: transparent;

        --a-normal-text: #6af;
        --a-normal-underline: #555;
        --a-visited-text: var(--a-normal-text);
        --a-visited-underline: var(--a-normal-underline);
        --a-hover-bg: rgba(25%, 25%, 25%, .2);
        --a-active-text: #f44;
        --a-active-underline: var(--a-active-text);

        --borderedblock-bg: rgba(255, 255, 255, .05);

        --blockquote-border: silver;
        --blockquote-bg: var(--borderedblock-bg);
        --blockquote-text: currentcolor;

        --issue-border: #e05252;
        --issue-bg: var(--borderedblock-bg);
        --issue-text: var(--text);
        --issueheading-text: hsl(0deg, 70%, 70%);

        --example-border: hsl(50deg, 90%, 60%);
        --example-bg: var(--borderedblock-bg);
        --example-text: var(--text);
        --exampleheading-text: hsl(50deg, 70%, 70%);

        --note-border: hsl(120deg, 100%, 35%);
        --note-bg: var(--borderedblock-bg);
        --note-text: var(--text);
        --noteheading-text: hsl(120, 70%, 70%);
        --notesummary-underline: silver;

        --assertion-border: #444;
        --assertion-bg: var(--borderedblock-bg);
        --assertion-text: var(--text);

        --advisement-border: orange;
        --advisement-bg: #222218;
        --advisement-text: var(--text);
        --advisementheading-text: #f84;

        --warning-border: red;
        --warning-bg: hsla(40,100%,20%,0.95);
        --warning-text: var(--text);

        --amendment-border: #330099;
        --amendment-bg: #080010;
        --amendment-text: var(--text);
        --amendmentheading-text: #cc00ff;

        --def-border: #8ccbf2;
        --def-bg: #080818;
        --def-text: var(--text);
        --defrow-border: #136;

        --datacell-border: silver;

        --indexinfo-text: #aaa;

        --indextable-hover-text: var(--text);
        --indextable-hover-bg: #181818;

        --outdatedspec-bg: rgba(255, 255, 255, .5);
        --outdatedspec-text: black;
        --outdated-bg: maroon;
        --outdated-text: white;
        --outdated-shadow: red;

        --editedrec-bg: darkorange;
    }
    /* In case a transparent-bg image doesn't expect to be on a dark bg,
       which is quite common in practice... */
    img { background: white; }
}
@media (prefers-color-scheme: dark) {
    :root {
        --selflink-text: black;
        --selflink-bg: silver;
        --selflink-hover-text: white;
    }
}

@media (prefers-color-scheme: dark) {
    .highlight:not(.idl) { background: rgba(255, 255, 255, .05); }

    c-[a] { color: #d33682 } /* Keyword.Declaration */
    c-[b] { color: #d33682 } /* Keyword.Type */
    c-[c] { color: #2aa198 } /* Comment */
    c-[d] { color: #2aa198 } /* Comment.Multiline */
    c-[e] { color: #268bd2 } /* Name.Attribute */
    c-[f] { color: #b58900 } /* Name.Tag */
    c-[g] { color: #cb4b16 } /* Name.Variable */
    c-[k] { color: #d33682 } /* Keyword */
    c-[l] { color: #657b83 } /* Literal */
    c-[m] { color: #657b83 } /* Literal.Number */
    c-[n] { color: #268bd2 } /* Name */
    c-[o] { color: #657b83 } /* Operator */
    c-[p] { color: #657b83 } /* Punctuation */
    c-[s] { color: #6c71c4 } /* Literal.String */
    c-[t] { color: #6c71c4 } /* Literal.String.Single */
    c-[u] { color: #6c71c4 } /* Literal.String.Double */
    c-[ch] { color: #2aa198 } /* Comment.Hashbang */
    c-[cp] { color: #2aa198 } /* Comment.Preproc */
    c-[cpf] { color: #2aa198 } /* Comment.PreprocFile */
    c-[c1] { color: #2aa198 } /* Comment.Single */
    c-[cs] { color: #2aa198 } /* Comment.Special */
    c-[kc] { color: #d33682 } /* Keyword.Constant */
    c-[kn] { color: #d33682 } /* Keyword.Namespace */
    c-[kp] { color: #d33682 } /* Keyword.Pseudo */
    c-[kr] { color: #d33682 } /* Keyword.Reserved */
    c-[ld] { color: #657b83 } /* Literal.Date */
    c-[nc] { color: #268bd2 } /* Name.Class */
    c-[no] { color: #268bd2 } /* Name.Constant */
    c-[nd] { color: #268bd2 } /* Name.Decorator */
    c-[ni] { color: #268bd2 } /* Name.Entity */
    c-[ne] { color: #268bd2 } /* Name.Exception */
    c-[nf] { color: #268bd2 } /* Name.Function */
    c-[nl] { color: #268bd2 } /* Name.Label */
    c-[nn] { color: #268bd2 } /* Name.Namespace */
    c-[py] { color: #268bd2 } /* Name.Property */
    c-[ow] { color: #657b83 } /* Operator.Word */
    c-[mb] { color: #657b83 } /* Literal.Number.Bin */
    c-[mf] { color: #657b83 } /* Literal.Number.Float */
    c-[mh] { color: #657b83 } /* Literal.Number.Hex */
    c-[mi] { color: #657b83 } /* Literal.Number.Integer */
    c-[mo] { color: #657b83 } /* Literal.Number.Oct */
    c-[sa] { color: #6c71c4 } /* Literal.String.Affix */
    c-[sb] { color: #6c71c4 } /* Literal.String.Backtick */
    c-[sc] { color: #6c71c4 } /* Literal.String.Char */
    c-[dl] { color: #6c71c4 } /* Literal.String.Delimiter */
    c-[sd] { color: #6c71c4 } /* Literal.String.Doc */
    c-[se] { color: #6c71c4 } /* Literal.String.Escape */
    c-[sh] { color: #6c71c4 } /* Literal.String.Heredoc */
    c-[si] { color: #6c71c4 } /* Literal.String.Interpol */
    c-[sx] { color: #6c71c4 } /* Literal.String.Other */
    c-[sr] { color: #6c71c4 } /* Literal.String.Regex */
    c-[ss] { color: #6c71c4 } /* Literal.String.Symbol */
    c-[fm] { color: #268bd2 } /* Name.Function.Magic */
    c-[vc] { color: #cb4b16 } /* Name.Variable.Class */
    c-[vg] { color: #cb4b16 } /* Name.Variable.Global */
    c-[vi] { color: #cb4b16 } /* Name.Variable.Instance */
    c-[vm] { color: #cb4b16 } /* Name.Variable.Magic */
    c-[il] { color: #657b83 } /* Literal.Number.Integer.Long */
}
</style>
 <body class="h-entry">
  <div class="head">
   <p data-fill-with="logo"></p>
   <h1 class="p-name no-ref" id="title">P1673R6<br>P1673R6: A free function linear algebra interface based on the BLAS</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="profile-and-date"><span class="content">Published Proposal, <time class="dt-updated" datetime="2021-12-15">2021-12-15</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>This version:
     <dd><a class="u-url" href="https://github.com/ORNL/cpp-proposals-pub/blob/master/D1673/P1673.bs">https://github.com/ORNL/cpp-proposals-pub/blob/master/D1673/P1673.bs</a>
     <dt class="editor">Author:
     <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:mhoemmen@stellarscience.com">Mark Hoemmen</a> (<a class="p-org org" href="https://www.stellarscience.com">Stellar Science</a>)
     <dt>Project:
     <dd>ISO/IEC JTC1/SC22/WG21 14882: Programming Language — C++
    </dl>
   </div>
   <div data-fill-with="warning"></div>
   <hr title="Separator for header">
  </div>
  <div class="p-summary" data-fill-with="abstract">
   <h2 class="no-num no-toc no-ref heading settled" id="abstract"><span class="content">Abstract</span></h2>
   <p>We propose a C++ Standard Library dense linear algebra interface based on the dense Basic Linear Algebra Subroutines (BLAS).  This corresponds to a subset of the BLAS Standard.</p>
  </div>
  <nav data-fill-with="table-of-contents" id="toc">
   <h2 class="no-num no-toc no-ref" id="contents">Table of Contents</h2>
   <ol class="toc" role="directory">
    <li>
     <a href="#authors-and-contributors"><span class="secno">1</span> <span class="content">Authors and contributors</span></a>
     <ol class="toc">
      <li><a href="#authors"><span class="secno">1.1</span> <span class="content">Authors</span></a>
      <li><a href="#contributors"><span class="secno">1.2</span> <span class="content">Contributors</span></a>
     </ol>
    <li><a href="#revision-history"><span class="secno">2</span> <span class="content">Revision history</span></a>
    <li><a href="#purpose-of-this-paper"><span class="secno">3</span> <span class="content">Purpose of this paper</span></a>
    <li><a href="#overview-of-contents"><span class="secno">4</span> <span class="content">Overview of contents</span></a>
    <li><a href="#interoperable-with-other-linear-algebra-proposals"><span class="secno">5</span> <span class="content">Interoperable with other linear algebra proposals</span></a>
    <li><a href="#why-include-dense-linear-algebra-in-the-c-standard-library"><span class="secno">6</span> <span class="content">Why include dense linear algebra in the C++ Standard Library?</span></a>
    <li><a href="#why-base-a-c-linear-algebra-library-on-the-blas"><span class="secno">7</span> <span class="content">Why base a C++ linear algebra library on the BLAS?</span></a>
    <li><a href="#criteria-for-including-algorithms"><span class="secno">8</span> <span class="content">Criteria for including algorithms</span></a>
    <li>
     <a href="#notation-and-conventions"><span class="secno">9</span> <span class="content">Notation and conventions</span></a>
     <ol class="toc">
      <li><a href="#the-blas-uses-fortran-terms"><span class="secno">9.1</span> <span class="content">The BLAS uses Fortran terms</span></a>
      <li><a href="#we-call-subroutines-functions"><span class="secno">9.2</span> <span class="content">We call "subroutines" functions</span></a>
      <li><a href="#element-types-and-blas-function-name-prefix"><span class="secno">9.3</span> <span class="content">Element types and BLAS function name prefix</span></a>
     </ol>
    <li>
     <a href="#what-we-exclude-from-the-design"><span class="secno">10</span> <span class="content">What we exclude from the design</span></a>
     <ol class="toc">
      <li><a href="#most-functions-not-in-the-reference-blas"><span class="secno">10.1</span> <span class="content">Most functions not in the Reference BLAS</span></a>
      <li><a href="#lapack-or-related-functionality"><span class="secno">10.2</span> <span class="content">LAPACK or related functionality</span></a>
      <li><a href="#extended-precision-blas"><span class="secno">10.3</span> <span class="content">Extended-precision BLAS</span></a>
      <li><a href="#arithmetic-operators-and-associated-expression-templates"><span class="secno">10.4</span> <span class="content">Arithmetic operators and associated expression templates</span></a>
      <li><a href="#banded-matrix-layouts"><span class="secno">10.5</span> <span class="content">Banded matrix layouts</span></a>
      <li><a href="#tensors"><span class="secno">10.6</span> <span class="content">Tensors</span></a>
      <li><a href="#explicit-support-for-asynchronous-return-of-scalar-values"><span class="secno">10.7</span> <span class="content">Explicit support for asynchronous return of scalar values</span></a>
     </ol>
    <li>
     <a href="#design-justification"><span class="secno">11</span> <span class="content">Design justification</span></a>
     <ol class="toc">
      <li><a href="#we-do-not-require-using-the-blas-library"><span class="secno">11.1</span> <span class="content">We do not require using the BLAS library</span></a>
      <li>
       <a href="#why-use-mdspan"><span class="secno">11.2</span> <span class="content">Why use <code class="highlight"><c- n>mdspan</c-></code>?</span></a>
       <ol class="toc">
        <li><a href="#view-of-a-multidimensional-array"><span class="secno">11.2.1</span> <span class="content">View of a multidimensional array</span></a>
        <li><a href="#ease-of-use"><span class="secno">11.2.2</span> <span class="content">Ease of use</span></a>
        <li><a href="#blas-and-mdspan-are-low-level"><span class="secno">11.2.3</span> <span class="content">BLAS and <code class="highlight"><c- n>mdspan</c-></code> are low level</span></a>
        <li><a href="#hook-for-future-expansion"><span class="secno">11.2.4</span> <span class="content">Hook for future expansion</span></a>
        <li><a href="#generic-enough-to-replace-a-multidimensional-array-concept"><span class="secno">11.2.5</span> <span class="content">Generic enough to replace a "multidimensional array concept"</span></a>
       </ol>
      <li><a href="#function-argument-aliasing-and-zero-scalar-multipliers"><span class="secno">11.3</span> <span class="content">Function argument aliasing and zero scalar multipliers</span></a>
      <li><a href="#support-for-different-matrix-layouts"><span class="secno">11.4</span> <span class="content">Support for different matrix layouts</span></a>
      <li><a href="#over--and-underflow-wording-for-vector-2-norm"><span class="secno">11.5</span> <span class="content">Over- and underflow wording for vector 2-norm</span></a>
      <li>
       <a href="#constraining-matrix-and-vector-element-types-and-scalars"><span class="secno">11.6</span> <span class="content">Constraining matrix and vector element types and scalars</span></a>
       <ol class="toc">
        <li><a href="#introduction"><span class="secno">11.6.1</span> <span class="content">Introduction</span></a>
        <li><a href="#value-type-constraints-do-not-suffice-to-describe-algorithm-behavior"><span class="secno">11.6.2</span> <span class="content">Value type constraints do not suffice to describe algorithm behavior</span></a>
        <li><a href="#associativity-is-too-strict"><span class="secno">11.6.3</span> <span class="content">Associativity is too strict</span></a>
        <li><a href="#generalizing-associativity-helps-little"><span class="secno">11.6.4</span> <span class="content">Generalizing associativity helps little</span></a>
        <li><a href="#categories-of-qoi-enhancements"><span class="secno">11.6.5</span> <span class="content">Categories of QoI enhancements</span></a>
        <li><a href="#properties-of-textbook-algorithm-descriptions"><span class="secno">11.6.6</span> <span class="content">Properties of textbook algorithm descriptions</span></a>
        <li>
         <a href="#reordering-sums-and-creating-temporaries"><span class="secno">11.6.7</span> <span class="content">Reordering sums and creating temporaries</span></a>
         <ol class="toc">
          <li><a href="#special-case-only-one-element-type"><span class="secno">11.6.7.1</span> <span class="content">Special case: Only one element type</span></a>
          <li>
           <a href="#general-case-multiple-input-element-types"><span class="secno">11.6.7.2</span> <span class="content">General case: Multiple input element types</span></a>
           <ol class="toc">
            <li><a href="#accumulate-into-output-value-type"><span class="secno">11.6.7.2.1</span> <span class="content">Accumulate into output value type</span></a>
            <li><a href="#proxy-references-or-expression-templates"><span class="secno">11.6.7.2.2</span> <span class="content">Proxy references or expression templates</span></a>
           </ol>
         </ol>
        <li>
         <a href="#textbook-algorithm-description-in-semiring-terms"><span class="secno">11.6.8</span> <span class="content">"Textbook" algorithm description in semiring terms</span></a>
         <ol class="toc">
          <li><a href="#why-a-semiring"><span class="secno">11.6.8.1</span> <span class="content">Why a semiring?</span></a>
          <li><a href="#semirings-and-testing"><span class="secno">11.6.8.2</span> <span class="content">Semirings and testing</span></a>
          <li><a href="#commutative-multiplication"><span class="secno">11.6.8.3</span> <span class="content">Commutative multiplication</span></a>
          <li><a href="#noncommutative-multiplication"><span class="secno">11.6.8.4</span> <span class="content">Noncommutative multiplication</span></a>
         </ol>
        <li><a href="#summary"><span class="secno">11.6.9</span> <span class="content">Summary</span></a>
       </ol>
     </ol>
    <li>
     <a href="#future-work"><span class="secno">12</span> <span class="content">Future work</span></a>
     <ol class="toc">
      <li><a href="#generalize-function-parameters"><span class="secno">12.1</span> <span class="content">Generalize function parameters</span></a>
      <li><a href="#batched-linear-algebra"><span class="secno">12.2</span> <span class="content">Batched linear algebra</span></a>
     </ol>
    <li>
     <a href="#data-structures-and-utilities-borrowed-from-other-proposals"><span class="secno">13</span> <span class="content">Data structures and utilities borrowed from other proposals</span></a>
     <ol class="toc">
      <li><a href="#mdspan"><span class="secno">13.1</span> <span class="content"><code class="highlight"><c- n>mdspan</c-></code></span></a>
      <li><a href="#new-mdspan-layouts-in-this-proposal"><span class="secno">13.2</span> <span class="content">New <code class="highlight"><c- n>mdspan</c-></code> layouts in this proposal</span></a>
     </ol>
    <li><a href="#acknowledgments"><span class="secno">14</span> <span class="content">Acknowledgments</span></a>
    <li>
     <a href="#references"><span class="secno">15</span> <span class="content">References</span></a>
     <ol class="toc">
      <li><a href="#references-by-coathors"><span class="secno">15.1</span> <span class="content">References by coathors</span></a>
      <li><a href="#other-references"><span class="secno">15.2</span> <span class="content">Other references</span></a>
     </ol>
    <li>
     <a href="#wording"><span class="secno">16</span> <span class="content">Wording</span></a>
     <ol class="toc">
      <li><a href="#header-linalg-synopsis-linalgsyn"><span class="secno">16.1</span> <span class="content">Header <code class="highlight"><c- o>&lt;</c-><c- n>linalg</c-><c- o>></c-></code> synopsis [linalg.syn]</span></a>
      <li>
       <a href="#requirements-linalgreqs"><span class="secno">16.2</span> <span class="content">Requirements [linalg.reqs]</span></a>
       <ol class="toc">
        <li><a href="#value-and-reference-requirements-linalgreqsval"><span class="secno">16.2.1</span> <span class="content">Value and reference requirements [linalg.reqs.val]</span></a>
        <li><a href="#requirements-for-algorithms-and-methods-on-floating-point-values-linalgreqsflpt"><span class="secno">16.2.2</span> <span class="content">Requirements for algorithms and methods on floating-point values [linalg.reqs.flpt]</span></a>
       </ol>
      <li>
       <a href="#tag-classes-linalgtags"><span class="secno">16.3</span> <span class="content">Tag classes [linalg.tags]</span></a>
       <ol class="toc">
        <li><a href="#storage-order-tags-linalgtagsorder"><span class="secno">16.3.1</span> <span class="content">Storage order tags [linalg.tags.order]</span></a>
        <li><a href="#triangle-tags-linalgtagstriangle"><span class="secno">16.3.2</span> <span class="content">Triangle tags [linalg.tags.triangle]</span></a>
        <li><a href="#diagonal-tags-linalgtagsdiagonal"><span class="secno">16.3.3</span> <span class="content">Diagonal tags [linalg.tags.diagonal]</span></a>
       </ol>
      <li>
       <a href="#layouts-for-general-and-packed-matrix-types-linalglayouts"><span class="secno">16.4</span> <span class="content">Layouts for general and packed matrix types [linalg.layouts]</span></a>
       <ol class="toc">
        <li><a href="#layout_blas_general-linalglayoutsgeneral"><span class="secno">16.4.1</span> <span class="content"><code class="highlight"><c- n>layout_blas_general</c-></code> [linalg.layouts.general]</span></a>
        <li><a href="#layout_blas_packed-linalglayoutspacked"><span class="secno">16.4.2</span> <span class="content"><code class="highlight"><c- n>layout_blas_packed</c-></code> [linalg.layouts.packed]</span></a>
       </ol>
      <li>
       <a href="#scaled-in-place-transformation-linalgscaled"><span class="secno">16.5</span> <span class="content">Scaled in-place transformation [linalg.scaled]</span></a>
       <ol class="toc">
        <li><a href="#class-template-accessor_scaled-linalgscaledaccessor_scaled"><span class="secno">16.5.1</span> <span class="content">Class template <code class="highlight"><c- n>accessor_scaled</c-></code> [linalg.scaled.accessor_scaled]</span></a>
        <li><a href="#scaled-linalgscaledscaled"><span class="secno">16.5.2</span> <span class="content"><code class="highlight"><c- n>scaled</c-></code> [linalg.scaled.scaled]</span></a>
       </ol>
      <li>
       <a href="#conjugated-in-place-transformation-linalgconj"><span class="secno">16.6</span> <span class="content">Conjugated in-place transformation [linalg.conj]</span></a>
       <ol class="toc">
        <li><a href="#class-template-accessor_conjugate-linalgconjaccessor_conjugate"><span class="secno">16.6.1</span> <span class="content">Class template <code class="highlight"><c- n>accessor_conjugate</c-></code> [linalg.conj.accessor_conjugate]</span></a>
        <li><a href="#conjugated-linalgconjconjugated"><span class="secno">16.6.2</span> <span class="content"><code class="highlight"><c- n>conjugated</c-></code> [linalg.conj.conjugated]</span></a>
       </ol>
      <li>
       <a href="#transpose-in-place-transformation-linalgtransp"><span class="secno">16.7</span> <span class="content">Transpose in-place transformation [linalg.transp]</span></a>
       <ol class="toc">
        <li><a href="#layout_transpose-linalgtransplayout_transpose"><span class="secno">16.7.1</span> <span class="content"><code class="highlight"><c- n>layout_transpose</c-></code> [linalg.transp.layout_transpose]</span></a>
        <li><a href="#transposed-linalgtransptransposed"><span class="secno">16.7.2</span> <span class="content"><code class="highlight"><c- n>transposed</c-></code> [linalg.transp.transposed]</span></a>
       </ol>
      <li><a href="#conjugate-transpose-transform-linalgconj_transp"><span class="secno">16.8</span> <span class="content">Conjugate transpose transform [linalg.conj_transp]</span></a>
      <li>
       <a href="#algorithms-linalgalgs"><span class="secno">16.9</span> <span class="content">Algorithms [linalg.algs]</span></a>
       <ol class="toc">
        <li><a href="#requirements-based-on-template-parameter-name-linalgalgsreqs"><span class="secno">16.9.1</span> <span class="content">Requirements based on template parameter name [linalg.algs.reqs]</span></a>
        <li>
         <a href="#blas-1-functions-linalgalgsblas1"><span class="secno">16.9.2</span> <span class="content">BLAS 1 functions [linalg.algs.blas1]</span></a>
         <ol class="toc">
          <li>
           <a href="#givens-rotations-linalgalgsblas1givens"><span class="secno">16.9.2.1</span> <span class="content">Givens rotations [linalg.algs.blas1.givens]</span></a>
           <ol class="toc">
            <li><a href="#compute-givens-rotation-linalgalgsblas1givenslartg"><span class="secno">16.9.2.1.1</span> <span class="content">Compute Givens rotation [linalg.algs.blas1.givens.lartg]</span></a>
            <li><a href="#apply-a-computed-givens-rotation-to-vectors-linalgalgsblas1givensrot"><span class="secno">16.9.2.1.2</span> <span class="content">Apply a computed Givens rotation to vectors [linalg.algs.blas1.givens.rot]</span></a>
           </ol>
          <li><a href="#swap-matrix-or-vector-elements-linalgalgsblas1swap"><span class="secno">16.9.2.2</span> <span class="content">Swap matrix or vector elements [linalg.algs.blas1.swap]</span></a>
          <li><a href="#multiply-the-elements-of-an-object-in-place-by-a-scalar-linalgalgsblas1scal"><span class="secno">16.9.2.3</span> <span class="content">Multiply the elements of an object in place by a scalar [linalg.algs.blas1.scal]</span></a>
          <li><a href="#copy-elements-of-one-matrix-or-vector-into-another-linalgalgsblas1copy"><span class="secno">16.9.2.4</span> <span class="content">Copy elements of one matrix or vector into another [linalg.algs.blas1.copy]</span></a>
          <li><a href="#add-vectors-or-matrices-elementwise-linalgalgsblas1add"><span class="secno">16.9.2.5</span> <span class="content">Add vectors or matrices elementwise [linalg.algs.blas1.add]</span></a>
          <li>
           <a href="#dot-product-of-two-vectors-linalgalgsblas1dot"><span class="secno">16.9.2.6</span> <span class="content">Dot product of two vectors [linalg.algs.blas1.dot]</span></a>
           <ol class="toc">
            <li><a href="#nonconjugated-dot-product-of-two-vectors-linalgalgsblas1dotdotu"><span class="secno">16.9.2.6.1</span> <span class="content">Nonconjugated dot product of two vectors [linalg.algs.blas1.dot.dotu]</span></a>
            <li><a href="#conjugated-dot-product-of-two-vectors-linalgalgsblas1dotdotc"><span class="secno">16.9.2.6.2</span> <span class="content">Conjugated dot product of two vectors [linalg.algs.blas1.dot.dotc]</span></a>
           </ol>
          <li><a href="#scaled-sum-of-squares-of-a-vectors-elements-linalgalgsblas1ssq"><span class="secno">16.9.2.7</span> <span class="content">Scaled sum of squares of a vector’s elements [linalg.algs.blas1.ssq]</span></a>
          <li>
           <a href="#euclidean-norm-of-a-vector-linalgalgsblas1nrm2"><span class="secno">16.9.2.8</span> <span class="content">Euclidean norm of a vector [linalg.algs.blas1.nrm2]</span></a>
           <ol class="toc">
            <li><a href="#euclidean-norm-with-specified-result-type"><span class="secno">16.9.2.8.1</span> <span class="content">Euclidean norm with specified result type</span></a>
            <li><a href="#euclidean-norm-with-default-result-type"><span class="secno">16.9.2.8.2</span> <span class="content">Euclidean norm with default result type</span></a>
           </ol>
          <li>
           <a href="#sum-of-absolute-values-of-vector-elements-linalgalgsblas1asum"><span class="secno">16.9.2.9</span> <span class="content">Sum of absolute values of vector elements [linalg.algs.blas1.asum]</span></a>
           <ol class="toc">
            <li><a href="#sum-of-absolute-values-with-specified-result-type"><span class="secno">16.9.2.9.1</span> <span class="content">Sum of absolute values with specified result type</span></a>
            <li><a href="#sum-of-absolute-values-with-default-result-type"><span class="secno">16.9.2.9.2</span> <span class="content">Sum of absolute values with default result type</span></a>
           </ol>
          <li><a href="#index-of-maximum-absolute-value-of-vector-elements-linalgalgsblas1iamax"><span class="secno">16.9.2.10</span> <span class="content">Index of maximum absolute value of vector elements [linalg.algs.blas1.iamax]</span></a>
          <li>
           <a href="#frobenius-norm-of-a-matrix-linalgalgsblas1matfrobnorm"><span class="secno">16.9.2.11</span> <span class="content">Frobenius norm of a matrix [linalg.algs.blas1.matfrobnorm]</span></a>
           <ol class="toc">
            <li><a href="#frobenius-norm-with-specified-result-type"><span class="secno">16.9.2.11.1</span> <span class="content">Frobenius norm with specified result type</span></a>
            <li><a href="#frobenius-norm-with-default-result-type"><span class="secno">16.9.2.11.2</span> <span class="content">Frobenius norm with default result type</span></a>
           </ol>
          <li>
           <a href="#one-norm-of-a-matrix-linalgalgsblas1matonenorm"><span class="secno">16.9.2.12</span> <span class="content">One norm of a matrix [linalg.algs.blas1.matonenorm]</span></a>
           <ol class="toc">
            <li><a href="#one-norm-with-specified-result-type"><span class="secno">16.9.2.12.1</span> <span class="content">One norm with specified result type</span></a>
            <li><a href="#one-norm-with-default-result-type"><span class="secno">16.9.2.12.2</span> <span class="content">One norm with default result type</span></a>
           </ol>
          <li>
           <a href="#infinity-norm-of-a-matrix-linalgalgsblas1matinfnorm"><span class="secno">16.9.2.13</span> <span class="content">Infinity norm of a matrix [linalg.algs.blas1.matinfnorm]</span></a>
           <ol class="toc">
            <li><a href="#infinity-norm-with-specified-result-type"><span class="secno">16.9.2.13.1</span> <span class="content">Infinity norm with specified result type</span></a>
            <li><a href="#infinity-norm-with-default-result-type"><span class="secno">16.9.2.13.2</span> <span class="content">Infinity norm with default result type</span></a>
           </ol>
         </ol>
        <li>
         <a href="#blas-2-functions-linalgalgsblas2"><span class="secno">16.9.3</span> <span class="content">BLAS 2 functions [linalg.algs.blas2]</span></a>
         <ol class="toc">
          <li>
           <a href="#general-matrix-vector-product-linalgalgsblas2gemv"><span class="secno">16.9.3.1</span> <span class="content">General matrix-vector product [linalg.algs.blas2.gemv]</span></a>
           <ol class="toc">
            <li><a href="#overwriting-matrix-vector-product"><span class="secno">16.9.3.1.1</span> <span class="content">Overwriting matrix-vector product</span></a>
            <li><a href="#updating-matrix-vector-product"><span class="secno">16.9.3.1.2</span> <span class="content">Updating matrix-vector product</span></a>
           </ol>
          <li>
           <a href="#symmetric-matrix-vector-product-linalgalgsblas2symv"><span class="secno">16.9.3.2</span> <span class="content">Symmetric matrix-vector product [linalg.algs.blas2.symv]</span></a>
           <ol class="toc">
            <li><a href="#overwriting-symmetric-matrix-vector-product"><span class="secno">16.9.3.2.1</span> <span class="content">Overwriting symmetric matrix-vector product</span></a>
            <li><a href="#updating-symmetric-matrix-vector-product"><span class="secno">16.9.3.2.2</span> <span class="content">Updating symmetric matrix-vector product</span></a>
           </ol>
          <li>
           <a href="#hermitian-matrix-vector-product-linalgalgsblas2hemv"><span class="secno">16.9.3.3</span> <span class="content">Hermitian matrix-vector product [linalg.algs.blas2.hemv]</span></a>
           <ol class="toc">
            <li><a href="#overwriting-hermitian-matrix-vector-product"><span class="secno">16.9.3.3.1</span> <span class="content">Overwriting Hermitian matrix-vector product</span></a>
            <li><a href="#updating-hermitian-matrix-vector-product"><span class="secno">16.9.3.3.2</span> <span class="content">Updating Hermitian matrix-vector product</span></a>
           </ol>
          <li>
           <a href="#triangular-matrix-vector-product-linalgalgsblas2trmv"><span class="secno">16.9.3.4</span> <span class="content">Triangular matrix-vector product [linalg.algs.blas2.trmv]</span></a>
           <ol class="toc">
            <li><a href="#overwriting-triangular-matrix-vector-product-linalgalgsblas2trmvov"><span class="secno">16.9.3.4.1</span> <span class="content">Overwriting triangular matrix-vector product [linalg.algs.blas2.trmv.ov]</span></a>
            <li><a href="#in-place-triangular-matrix-vector-product-linalgalgsblas2trmvin-place"><span class="secno">16.9.3.4.2</span> <span class="content">In-place triangular matrix-vector product [linalg.algs.blas2.trmv.in-place]</span></a>
            <li><a href="#updating-triangular-matrix-vector-product-linalgalgsblas2trmvup"><span class="secno">16.9.3.4.3</span> <span class="content">Updating triangular matrix-vector product [linalg.algs.blas2.trmv.up]</span></a>
           </ol>
          <li>
           <a href="#solve-a-triangular-linear-system-linalgalgsblas2trsv"><span class="secno">16.9.3.5</span> <span class="content">Solve a triangular linear system [linalg.algs.blas2.trsv]</span></a>
           <ol class="toc">
            <li><a href="#not-in-place-triangular-solve-linalgalgsblas2trsvnot-in-place"><span class="secno">16.9.3.5.1</span> <span class="content">Not-in-place triangular solve [linalg.algs.blas2.trsv.not-in-place]</span></a>
            <li><a href="#in-place-triangular-solve-linalgalgsblas2trsvin-place"><span class="secno">16.9.3.5.2</span> <span class="content">In-place triangular solve [linalg.algs.blas2.trsv.in-place]</span></a>
           </ol>
          <li>
           <a href="#rank-1-outer-product-update-of-a-matrix-linalgalgsblas2rank1"><span class="secno">16.9.3.6</span> <span class="content">Rank-1 (outer product) update of a matrix [linalg.algs.blas2.rank1]</span></a>
           <ol class="toc">
            <li><a href="#nonsymmetric-nonconjugated-rank-1-update-linalgalgsblas2rank1geru"><span class="secno">16.9.3.6.1</span> <span class="content">Nonsymmetric nonconjugated rank-1 update [linalg.algs.blas2.rank1.geru]</span></a>
            <li><a href="#nonsymmetric-conjugated-rank-1-update-linalgalgsblas2rank1gerc"><span class="secno">16.9.3.6.2</span> <span class="content">Nonsymmetric conjugated rank-1 update [linalg.algs.blas2.rank1.gerc]</span></a>
            <li><a href="#rank-1-update-of-a-symmetric-matrix-linalgalgsblas2rank1syr"><span class="secno">16.9.3.6.3</span> <span class="content">Rank-1 update of a Symmetric matrix [linalg.algs.blas2.rank1.syr]</span></a>
            <li><a href="#rank-1-update-of-a-hermitian-matrix-linalgalgsblas2rank1her"><span class="secno">16.9.3.6.4</span> <span class="content">Rank-1 update of a Hermitian matrix [linalg.algs.blas2.rank1.her]</span></a>
           </ol>
          <li><a href="#rank-2-update-of-a-symmetric-matrix-linalgalgsblas2rank2syr2"><span class="secno">16.9.3.7</span> <span class="content">Rank-2 update of a symmetric matrix [linalg.algs.blas2.rank2.syr2]</span></a>
          <li><a href="#rank-2-update-of-a-hermitian-matrix-linalgalgsblas2rank2her2"><span class="secno">16.9.3.8</span> <span class="content">Rank-2 update of a Hermitian matrix [linalg.algs.blas2.rank2.her2]</span></a>
         </ol>
        <li>
         <a href="#blas-3-functions-linalgalgsblas3"><span class="secno">16.9.4</span> <span class="content">BLAS 3 functions [linalg.algs.blas3]</span></a>
         <ol class="toc">
          <li>
           <a href="#general-matrix-matrix-product-linalgalgsblas3gemm"><span class="secno">16.9.4.1</span> <span class="content">General matrix-matrix product [linalg.algs.blas3.gemm]</span></a>
           <ol class="toc">
            <li><a href="#overwriting-general-matrix-matrix-product"><span class="secno">16.9.4.1.1</span> <span class="content">Overwriting general matrix-matrix product</span></a>
            <li><a href="#updating-general-matrix-matrix-product"><span class="secno">16.9.4.1.2</span> <span class="content">Updating general matrix-matrix product</span></a>
           </ol>
          <li>
           <a href="#symmetric-matrix-matrix-product-linalgalgsblas3symm"><span class="secno">16.9.4.2</span> <span class="content">Symmetric matrix-matrix product [linalg.algs.blas3.symm]</span></a>
           <ol class="toc">
            <li><a href="#overwriting-symmetric-matrix-matrix-left-product-linalgalgsblas3symmovleft"><span class="secno">16.9.4.2.1</span> <span class="content">Overwriting symmetric matrix-matrix left product [linalg.algs.blas3.symm.ov.left]</span></a>
            <li><a href="#overwriting-symmetric-matrix-matrix-right-product-linalgalgsblas3symmovright"><span class="secno">16.9.4.2.2</span> <span class="content">Overwriting symmetric matrix-matrix right product [linalg.algs.blas3.symm.ov.right]</span></a>
            <li><a href="#updating-symmetric-matrix-matrix-left-product-linalgalgsblas3symmupleft"><span class="secno">16.9.4.2.3</span> <span class="content">Updating symmetric matrix-matrix left product [linalg.algs.blas3.symm.up.left]</span></a>
            <li><a href="#updating-symmetric-matrix-matrix-right-product-linalgalgsblas3symmupright"><span class="secno">16.9.4.2.4</span> <span class="content">Updating symmetric matrix-matrix right product [linalg.algs.blas3.symm.up.right]</span></a>
           </ol>
          <li>
           <a href="#hermitian-matrix-matrix-product-linalgalgsblas3hemm"><span class="secno">16.9.4.3</span> <span class="content">Hermitian matrix-matrix product [linalg.algs.blas3.hemm]</span></a>
           <ol class="toc">
            <li><a href="#overwriting-hermitian-matrix-matrix-left-product-linalgalgsblas3hemmovleft"><span class="secno">16.9.4.3.1</span> <span class="content">Overwriting Hermitian matrix-matrix left product [linalg.algs.blas3.hemm.ov.left]</span></a>
            <li><a href="#overwriting-hermitian-matrix-matrix-right-product-linalgalgsblas3hemmovright"><span class="secno">16.9.4.3.2</span> <span class="content">Overwriting Hermitian matrix-matrix right product [linalg.algs.blas3.hemm.ov.right]</span></a>
            <li><a href="#updating-hermitian-matrix-matrix-left-product-linalgalgsblas3hemmupleft"><span class="secno">16.9.4.3.3</span> <span class="content">Updating Hermitian matrix-matrix left product [linalg.algs.blas3.hemm.up.left]</span></a>
            <li><a href="#updating-hermitian-matrix-matrix-right-product-linalgalgsblas3hemmupright"><span class="secno">16.9.4.3.4</span> <span class="content">Updating Hermitian matrix-matrix right product [linalg.algs.blas3.hemm.up.right]</span></a>
           </ol>
          <li>
           <a href="#triangular-matrix-matrix-product-linalgalgsblas3trmm"><span class="secno">16.9.4.4</span> <span class="content">Triangular matrix-matrix product [linalg.algs.blas3.trmm]</span></a>
           <ol class="toc">
            <li><a href="#overwriting-triangular-matrix-matrix-left-product-linalgalgsblas3trmmovleft"><span class="secno">16.9.4.4.1</span> <span class="content">Overwriting triangular matrix-matrix left product [linalg.algs.blas3.trmm.ov.left]</span></a>
            <li><a href="#overwriting-triangular-matrix-matrix-right-product-linalgalgsblas3trmmovright"><span class="secno">16.9.4.4.2</span> <span class="content">Overwriting triangular matrix-matrix right product [linalg.algs.blas3.trmm.ov.right]</span></a>
            <li><a href="#updating-triangular-matrix-matrix-left-product-linalgalgsblas3trmmupleft"><span class="secno">16.9.4.4.3</span> <span class="content">Updating triangular matrix-matrix left product [linalg.algs.blas3.trmm.up.left]</span></a>
            <li><a href="#updating-triangular-matrix-matrix-right-product-linalgalgsblas3trmmupright"><span class="secno">16.9.4.4.4</span> <span class="content">Updating triangular matrix-matrix right product [linalg.algs.blas3.trmm.up.right]</span></a>
           </ol>
          <li>
           <a href="#rank-k-update-of-a-symmetric-or-hermitian-matrix-linalgalgblas3rank-k"><span class="secno">16.9.4.5</span> <span class="content">Rank-k update of a symmetric or Hermitian matrix [linalg.alg.blas3.rank-k]</span></a>
           <ol class="toc">
            <li><a href="#rank-k-symmetric-matrix-update-linalgalgblas3rank-ksyrk"><span class="secno">16.9.4.5.1</span> <span class="content">Rank-k symmetric matrix update [linalg.alg.blas3.rank-k.syrk]</span></a>
            <li><a href="#rank-k-hermitian-matrix-update-linalgalgblas3rank-kherk"><span class="secno">16.9.4.5.2</span> <span class="content">Rank-k Hermitian matrix update [linalg.alg.blas3.rank-k.herk]</span></a>
           </ol>
          <li>
           <a href="#rank-2k-update-of-a-symmetric-or-hermitian-matrix-linalgalgblas3rank2k"><span class="secno">16.9.4.6</span> <span class="content">Rank-2k update of a symmetric or Hermitian matrix [linalg.alg.blas3.rank2k]</span></a>
           <ol class="toc">
            <li><a href="#rank-2k-symmetric-matrix-update-linalgalgblas3rank2ksyr2k"><span class="secno">16.9.4.6.1</span> <span class="content">Rank-2k symmetric matrix update [linalg.alg.blas3.rank2k.syr2k]</span></a>
            <li><a href="#rank-2k-hermitian-matrix-update-linalgalgblas3rank2kher2k"><span class="secno">16.9.4.6.2</span> <span class="content">Rank-2k Hermitian matrix update [linalg.alg.blas3.rank2k.her2k]</span></a>
           </ol>
          <li>
           <a href="#solve-multiple-triangular-linear-systems-linalgalgblas3trsm"><span class="secno">16.9.4.7</span> <span class="content">Solve multiple triangular linear systems [linalg.alg.blas3.trsm]</span></a>
           <ol class="toc">
            <li><a href="#solve-multiple-triangular-linear-systems-with-triangular-matrix-on-the-left-linalgalgblas3trsmleft"><span class="secno">16.9.4.7.1</span> <span class="content">Solve multiple triangular linear systems with triangular matrix on the left [linalg.alg.blas3.trsm.left]</span></a>
            <li><a href="#solve-multiple-triangular-linear-systems-with-triangular-matrix-on-the-right-linalgalgblas3trsmright"><span class="secno">16.9.4.7.2</span> <span class="content">Solve multiple triangular linear systems with triangular matrix on the right [linalg.alg.blas3.trsm.right]</span></a>
           </ol>
         </ol>
       </ol>
     </ol>
    <li>
     <a href="#examples"><span class="secno">17</span> <span class="content">Examples</span></a>
     <ol class="toc">
      <li><a href="#cholesky-factorization"><span class="secno">17.1</span> <span class="content">Cholesky factorization</span></a>
      <li><a href="#solve-linear-system-using-cholesky-factorization"><span class="secno">17.2</span> <span class="content">Solve linear system using Cholesky factorization</span></a>
      <li><a href="#compute-qr-factorization-of-a-tall-skinny-matrix"><span class="secno">17.3</span> <span class="content">Compute QR factorization of a tall skinny matrix</span></a>
     </ol>
   </ol>
  </nav>
  <main>
   <h2 class="heading settled" data-level="1" id="authors-and-contributors"><span class="secno">1. </span><span class="content">Authors and contributors</span><a class="self-link" href="#authors-and-contributors"></a></h2>
   <h3 class="heading settled" data-level="1.1" id="authors"><span class="secno">1.1. </span><span class="content">Authors</span><a class="self-link" href="#authors"></a></h3>
   <ul>
    <li data-md>
     <p>Mark Hoemmen (mhoemmen@stellarscience.com) (Stellar Science)</p>
    <li data-md>
     <p>Daisy Hollman (cpp@dsh.fyi) (Google)</p>
    <li data-md>
     <p>Christian Trott (crtrott@sandia.gov) (Sandia National Laboratories)</p>
    <li data-md>
     <p>Daniel Sunderland (dansunderland@gmail.com)</p>
    <li data-md>
     <p>Nevin Liber (nliber@anl.gov) (Argonne National Laboratory)</p>
    <li data-md>
     <p>Alicia Klinvex (alicia.klinvex@unnpp.gov) (Naval Nuclear Laboratory)</p>
    <li data-md>
     <p>Li-Ta Lo (ollie@lanl.gov) (Los Alamos National Laboratory)</p>
    <li data-md>
     <p>Damien Lebrun-Grandie (lebrungrandt@ornl.gov) (Oak Ridge National Laboratories)</p>
    <li data-md>
     <p>Graham Lopez (glopez@nvidia.com) (NVIDIA)</p>
    <li data-md>
     <p>Peter Caday (peter.caday@intel.com) (Intel)</p>
    <li data-md>
     <p>Sarah Knepper (sarah.knepper@intel.com) (Intel)</p>
    <li data-md>
     <p>Piotr Luszczek (luszczek@icl.utk.edu) (University of Tennessee)</p>
    <li data-md>
     <p>Timothy Costa (tcosta@nvidia.com) (NVIDIA)</p>
   </ul>
   <h3 class="heading settled" data-level="1.2" id="contributors"><span class="secno">1.2. </span><span class="content">Contributors</span><a class="self-link" href="#contributors"></a></h3>
   <ul>
    <li data-md>
     <p>Chip Freitag (chip.freitag@amd.com) (AMD)</p>
    <li data-md>
     <p>Bryce Adelstein Lelbach (brycelelbach@gmail.com) (NVIDIA)</p>
    <li data-md>
     <p>Srinath Vadlamani (Srinath.Vadlamani@arm.com) (ARM)</p>
    <li data-md>
     <p>Rene Vanoostrum (Rene.Vanoostrum@amd.com) (AMD)</p>
   </ul>
   <h2 class="heading settled" data-level="2" id="revision-history"><span class="secno">2. </span><span class="content">Revision history</span><a class="self-link" href="#revision-history"></a></h2>
   <ul>
    <li data-md>
     <p>Revision 0 (pre-Cologne) submitted 2019-06-17</p>
     <ul>
      <li data-md>
       <p>Received feedback in Cologne from SG6, LEWGI, and (???).</p>
     </ul>
    <li data-md>
     <p>Revision 1 (pre-Belfast) to be submitted 2019-10-07</p>
     <ul>
      <li data-md>
       <p>Account for Cologne 2019 feedback</p>
       <ul>
        <li data-md>
         <p>Make interface more consistent with existing Standard algorithms</p>
        <li data-md>
         <p>Change <code class="highlight"><c- n>dot</c-></code>, <code class="highlight"><c- n>dotc</c-></code>, <code class="highlight"><c- n>vector_norm2</c-></code>, and <code class="highlight"><c- n>vector_abs_sum</c-></code> to
imitate <code class="highlight"><c- n>reduce</c-></code>, so that they return their result, instead of
taking an output parameter.  Users may set the result type via
optional <code class="highlight"><c- n>init</c-></code> parameter.</p>
       </ul>
      <li data-md>
       <p>Minor changes to "expression template" classes, based on
implementation experience</p>
      <li data-md>
       <p>Briefly address LEWGI request of exploring concepts for input arguments.</p>
      <li data-md>
       <p>Lazy ranges style API was NOT explored.</p>
     </ul>
    <li data-md>
     <p>Revision 2 (pre-Cologne) to be submitted 2020-01-13</p>
     <ul>
      <li data-md>
       <p>Add "Future work" section.</p>
      <li data-md>
       <p>Remove "Options and votes" section (which were addressed in SG6,
SG14, and LEWGI).</p>
      <li data-md>
       <p>Remove <code class="highlight"><c- n>basic_mdarray</c-></code> overloads.</p>
      <li data-md>
       <p>Remove batched linear algebra operations.</p>
      <li data-md>
       <p>Remove over- and underflow requirement for <code class="highlight"><c- n>vector_norm2</c-></code>.</p>
      <li data-md>
       <p><em>Mandate</em> any extent compatibility checks that can be done at
compile time.</p>
      <li data-md>
       <p>Add missing functions <code class="highlight"><c- p>{</c-><c- n>symmetric</c-><c- p>,</c-><c- n>hermitian</c-><c- p>}</c-><c- n>_matrix_rank_k_update</c-></code> and <code class="highlight"><c- n>triangular_matrix_</c-><c- p>{</c-><c- n>left</c-><c- p>,</c-><c- n>right</c-><c- p>}</c-><c- n>_product</c-></code>.</p>
      <li data-md>
       <p>Remove <code class="highlight"><c- n>packed_view</c-></code> function.</p>
      <li data-md>
       <p>Fix wording for <code class="highlight"><c- p>{</c-><c- n>conjugate</c-><c- p>,</c-><c- n>transpose</c-><c- p>,</c-><c- n>conjugate_transpose</c-><c- p>}</c-><c- n>_view</c-></code>,
so that implementations may optimize the return type.  Make sure
that <code class="highlight"><c- n>transpose_view</c-></code> of a <code class="highlight"><c- n>layout_blas_packed</c-></code> matrix returns a <code class="highlight"><c- n>layout_blas_packed</c-></code> matrix with opposite <code class="highlight"><c- n>Triangle</c-></code> and <code class="highlight"><c- n>StorageOrder</c-></code>.</p>
      <li data-md>
       <p>Remove second template parameter <code class="highlight"><c- n>T</c-></code> from <code class="highlight"><c- n>accessor_conjugate</c-></code>.</p>
      <li data-md>
       <p>Make <code class="highlight"><c- n>scaled_scalar</c-></code> and <code class="highlight"><c- n>conjugated_scalar</c-></code> exposition only.</p>
      <li data-md>
       <p>Add in-place overloads of <code class="highlight"><c- n>triangular_matrix_matrix_</c-><c- p>{</c-><c- n>left</c-><c- p>,</c-><c- n>right</c-><c- p>}</c-><c- n>_solve</c-></code>, <code class="highlight"><c- n>triangular_matrix_</c-><c- p>{</c-><c- n>left</c-><c- p>,</c-><c- n>right</c-><c- p>}</c-><c- n>_product</c-></code>, and <code class="highlight"><c- n>triangular_matrix_vector_solve</c-></code>.</p>
      <li data-md>
       <p>Add <code class="highlight"><c- n>alpha</c-></code> overloads to <code class="highlight"><c- p>{</c-><c- n>symmetric</c-><c- p>,</c-><c- n>hermitian</c-><c- p>}</c-><c- n>_matrix_rank_</c-><c- p>{</c-><c- mi>1</c-><c- p>,</c-><c- n>k</c-><c- p>}</c-><c- n>_update</c-></code>.</p>
      <li data-md>
       <p>Add Cholesky factorization and solve examples.</p>
     </ul>
    <li data-md>
     <p>Revision 3 (electronic) to be submitted 2021-04-15</p>
     <ul>
      <li data-md>
       <p>Per LEWG request, add a section on our investigation
of constraining template parameters with concepts,
in the manner of P1813R0 with the numeric algorithms.
We concluded that we disagree with the approach of P1813R0,
and that the Standard’s current <em>GENERALIZED_SUM</em> approach
better expresses numeric algorithms' behavior.</p>
      <li data-md>
       <p>Update references to the current revision of P0009 (<code class="highlight"><c- n>mdspan</c-></code>).</p>
      <li data-md>
       <p>Per LEWG request, introduce <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>linalg</c-></code> namespace and put everything in there.</p>
      <li data-md>
       <p>Per LEWG request, replace the <code class="highlight"><c- n>linalg_</c-></code> prefix with the aforementioned namespace.
We renamed <code class="highlight"><c- n>linalg_add</c-></code> to <code class="highlight"><c- n>add</c-></code>, <code class="highlight"><c- n>linalg_copy</c-></code> to <code class="highlight"><c- n>copy</c-></code>, and <code class="highlight"><c- n>linalg_swap</c-></code> to <code class="highlight"><c- n>swap_elements</c-></code>.</p>
      <li data-md>
       <p>Per LEWG request, do not use <code class="highlight"><c- n>_view</c-></code> as a suffix,
to avoid confusion with "views" in the sense of Ranges.
We renamed <code class="highlight"><c- n>conjugate_view</c-></code> to <code class="highlight"><c- n>conjugated</c-></code>, <code class="highlight"><c- n>conjugate_transpose_view</c-></code> to <code class="highlight"><c- n>conjugate_transposed</c-></code>, <code class="highlight"><c- n>scaled_view</c-></code> to <code class="highlight"><c- n>scaled</c-></code>, and <code class="highlight"><c- n>transpose_view</c-></code> to <code class="highlight"><c- n>transposed</c-></code>.</p>
      <li data-md>
       <p>Change wording from "then implementations will use <code class="highlight"><c- n>T</c-></code>'s precision or greater
for intermediate terms in the sum,"
to "then intermediate terms in the sum use <code class="highlight"><c- n>T</c-></code>'s precision or greater."
Thanks to Jens Maurer for this suggestion (and many others!).</p>
      <li data-md>
       <p>Before, a Note on <code class="highlight"><c- n>vector_norm2</c-></code> said,
"We recommend that implementers document their guarantees regarding overflow and underflow
of <code class="highlight"><c- n>vector_norm2</c-></code> for floating-point return types."
Implementations always document "implementation-defined behavior" per <strong>[defs.impl.defined]</strong>.
(Thanks to Jens Maurer for pointing out that "We recommend..." does not belong in the Standard.)
Thus, we changed this from a Note to normative wording in Remarks:
"If either <code class="highlight"><c- n>in_vector_t</c-><c- o>::</c-><c- n>element_type</c-></code> or <code class="highlight"><c- n>T</c-></code> are
floating-point types or complex versions thereof,
then any guarantees regarding overflow and underflow of <code class="highlight"><c- n>vector_norm2</c-></code> are implementation-defined."</p>
      <li data-md>
       <p>Define return types of the <code class="highlight"><c- n>dot</c-></code>, <code class="highlight"><c- n>dotc</c-></code>, <code class="highlight"><c- n>vector_norm2</c-></code>, and <code class="highlight"><c- n>vector_abs_sum</c-></code> overloads
with <code class="highlight"><c- k>auto</c-></code> return type.</p>
      <li data-md>
       <p>Remove the explicitly stated constraint on <code class="highlight"><c- n>add</c-></code> and <code class="highlight"><c- n>copy</c-></code> that the rank of the array arguments be no more than 2.
This is redundant, because we already impose this
via the existing constraints on template parameters named <code class="highlight"><c- n>in_object</c-><c- o>*</c-><c- n>_t</c-></code>, <code class="highlight"><c- n>inout_object</c-><c- o>*</c-><c- n>_t</c-></code>, or <code class="highlight"><c- n>out_object</c-><c- o>*</c-><c- n>_t</c-></code>.
If we later wish to relax this restriction,
then we only have to do so in one place.</p>
      <li data-md>
       <p>Add <code class="highlight"><c- n>vector_sum_of_squares</c-></code>.
First, this gives implementers a path to implementing <code class="highlight"><c- n>vector_norm2</c-></code> in a way that achieves the over/underflow guarantees
intended by the BLAS Standard.
Second, this is a useful algorithm in itself
for parallelizing vector 2-norm computation.</p>
      <li data-md>
       <p>Add <code class="highlight"><c- n>matrix_frob_norm</c-></code>, <code class="highlight"><c- n>matrix_one_norm</c-></code>, and <code class="highlight"><c- n>matrix_inf_norm</c-></code> (thanks to coauthor Piotr Luszczek).</p>
      <li data-md>
       <p>Address LEWG request for us to investigate support for GPU memory.
See section "Explicit support for asynchronous return of scalar values."</p>
      <li data-md>
       <p>Add <code class="highlight"><c- n>ExecutionPolicy</c-></code> overloads of the in-place versions of <code class="highlight"><c- n>triangular_matrix_vector_solve</c-></code>, <code class="highlight"><c- n>triangular_matrix_left_product</c-></code>, <code class="highlight"><c- n>triangular_matrix_right_product</c-></code>, <code class="highlight"><c- n>triangular_matrix_matrix_left_solve</c-></code>, and <code class="highlight"><c- n>triangular_matrix_matrix_right_solve</c-></code>.</p>
     </ul>
    <li data-md>
     <p>Revision 4 (electronic), to be submitted 2021-08-15</p>
     <ul>
      <li data-md>
       <p>Update authors' contact info.</p>
      <li data-md>
       <p>Rebase atop P2299R3, which in turn sits atop P0009R12.
Make any needed fixes due to these changes.
(P1673R3 was based on P0009R10, without P2299.)
Update P0009 references to point to the latest version (R12).</p>
      <li data-md>
       <p>Fix requirements for <code class="highlight"><c- p>{</c-><c- n>symmetric</c-><c- p>,</c-><c- n>hermitian</c-><c- p>}</c-><c- n>_matrix_</c-><c- p>{</c-><c- n>left</c-><c- p>,</c-><c- n>right</c-><c- p>}</c-><c- n>_product</c-></code>.</p>
      <li data-md>
       <p>Change <code class="highlight"><c- n>SemiRegular</c-><c- o>&lt;</c-><c- n>Scalar</c-><c- o>></c-></code> to <code class="highlight"><c- n>semiregular</c-><c- o>&lt;</c-><c- n>Scalar</c-><c- o>></c-></code>.</p>
      <li data-md>
       <p>Make <code class="highlight"><c- n>Real</c-></code> requirements refer to <strong>[complex.numbers.general]</strong>,
rather than explicitly listing allowed types.
Remove redundant constraints on <code class="highlight"><c- n>Real</c-></code>.</p>
      <li data-md>
       <p>In <strong>[linalg.algs.reqs]</strong>, clarify that "unique layout"
for output matrix, vector, or object types
means <code class="highlight"><c- n>is_always_unique</c-><c- p>()</c-></code> equals <code class="highlight">true</code>.</p>
      <li data-md>
       <p>Change file format from Markdown to Bikeshed.</p>
      <li data-md>
       <p>Impose requirements on the types on which algorithms compute,
and on the algorithms themselves (e.g., what rearrangements are permitted).
Add a section explaining how we came up with the requirements.
Lift the requirements into a new higher-level section
that applies to the entire contents of <strong>[linalg]</strong>,
not just to <strong>[linalg.algs]</strong>.</p>
      <li data-md>
       <p>Add "Overview of contents" section.</p>
      <li data-md>
       <p>In the last review, LEWG had asked us to consider using exposition-only concepts
and <code class="highlight"><c- k>requires</c-></code> clauses to express requirements more clearly.
We decided not to do so, because we did not think it would add clarity.</p>
      <li data-md>
       <p>Add more examples.</p>
     </ul>
    <li data-md>
     <p>Revision 5 (electronic), to be submitted 2021-10-15</p>
     <ul>
      <li data-md>
       <p>P0009R13 (to be submitted 2021-10-15) changes <code class="highlight"><c- n>mdspan</c-></code> to use <code class="highlight"><c- k>operator</c-><c- p>[]</c-></code> instead of <code class="highlight"><c- k>operator</c-><c- p>()</c-></code> as the array access operator.
Revision 5 of P1673 adopts this change, and is "rebased" atop P1673R5.</p>
     </ul>
    <li data-md>
     <p>Revision 6 (electronic), to be submitted 2021-12-15</p>
     <ul>
      <li data-md>
       <p>Update references to P0009 (P0009R14) and P2128 (P2128R6).</p>
      <li data-md>
       <p>Fix typos in <code class="highlight"><c- o>*</c-><c- n>rank_2k</c-></code> descriptions.</p>
      <li data-md>
       <p>Remove references to any <code class="highlight"><c- n>mdspan</c-></code> rank greater than 2.
(These were left over from earlier versions of the proposal
that included "batched" operations.)</p>
      <li data-md>
       <p>Fix <code class="highlight"><c- n>vector_sum_of_squares</c-></code> name in BLAS comparison table.</p>
      <li data-md>
       <p>Replace "Requires" with "Preconditions," per new wording guidelines.</p>
      <li data-md>
       <p>Remove all overloads of <code class="highlight"><c- n>symmetric_matrix_rank_k_update</c-></code> and <code class="highlight"><c- n>hermitian_matrix_rank_k_update</c-></code> that do not take an <code class="highlight"><c- n>alpha</c-></code> parameter.
This prevents ambiguity between overloads
that take <code class="highlight"><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-></code> but not <code class="highlight"><c- n>alpha</c-></code>,
and overloads that take <code class="highlight"><c- n>alpha</c-></code> but not <code class="highlight"><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-></code>.</p>
      <li data-md>
       <p>Harmonize with the implementation, by adding <code class="highlight"><c- k>operator</c-><c- o>+</c-></code>, <code class="highlight"><c- k>operator</c-><c- o>*</c-></code>,
and comparison operators to <code class="highlight"><c- n>conjugated_scalar</c-></code>.</p>
     </ul>
   </ul>
   <h2 class="heading settled" data-level="3" id="purpose-of-this-paper"><span class="secno">3. </span><span class="content">Purpose of this paper</span><a class="self-link" href="#purpose-of-this-paper"></a></h2>
   <p>This paper proposes a C++ Standard Library dense linear algebra
interface based on the dense Basic Linear Algebra Subroutines (BLAS).
This corresponds to a subset of the <a href="http://www.netlib.org/blas/blast-forum/blas-report.pdf">BLAS Standard</a>.
Our proposal implements the following classes of algorithms on arrays that represent
matrices and vectors:</p>
   <ul>
    <li data-md>
     <p>Elementwise vector sums</p>
    <li data-md>
     <p>Multiplying all elements of a vector or matrix by a scalar</p>
    <li data-md>
     <p>2-norms and 1-norms of vectors</p>
    <li data-md>
     <p>Vector-vector, matrix-vector, and matrix-matrix products (contractions)</p>
    <li data-md>
     <p>Low-rank updates of a matrix</p>
    <li data-md>
     <p>Triangular solves with one or more "right-hand side" vectors</p>
    <li data-md>
     <p>Generating and applying plane (Givens) rotations</p>
   </ul>
   <p>Our algorithms work with most of the matrix storage formats that the BLAS
Standard supports:</p>
   <ul>
    <li data-md>
     <p>"General" dense matrices, in column-major or row-major format</p>
    <li data-md>
     <p>Symmetric or Hermitian (for complex numbers only) dense matrices,
stored either as general dense matrices, or in a packed format</p>
    <li data-md>
     <p>Dense triangular matrices, stored either as general dense matrices
or in a packed format</p>
   </ul>
   <p>Our proposal also has the following distinctive characteristics:</p>
   <ul>
    <li data-md>
     <p>It uses free functions, not arithmetic operator overloading.</p>
    <li data-md>
     <p>The interface is designed in the spirit of the C++ Standard Library’s
algorithms.</p>
    <li data-md>
     <p>It uses <code class="highlight"><c- n>mdspan</c-></code> (see P0009),
a multidimensional array view, to represent matrices and vectors.
In the future,
it could support other proposals' matrix and vector data structures.</p>
    <li data-md>
     <p>The interface permits optimizations for matrices and vectors with
small compile-time dimensions; the standard BLAS interface does not.</p>
    <li data-md>
     <p>Each of our proposed operations supports all element types for which
that operation makes sense, unlike the BLAS, which only supports
four element types.</p>
    <li data-md>
     <p>Our operations permit "mixed-precision" computation with matrices
and vectors that have different element types.  This subsumes most
functionality of the Mixed-Precision BLAS specification (Chapter 4
of the <a href="http://www.netlib.org/blas/blast-forum/blas-report.pdf">BLAS
Standard</a>).</p>
    <li data-md>
     <p>Like the C++ Standard Library’s algorithms, our operations take an
optional execution policy argument.  This is a hook to support
parallel execution and hierarchical parallelism (through the
proposed executor extensions to execution policies; see
P1019R2).</p>
    <li data-md>
     <p>Unlike the BLAS, our proposal can be expanded to support "batched"
operations (see P1417R0) with almost no
interface differences.  This will support machine learning and other
applications that need to do many small matrix or vector operations
at once.</p>
   </ul>
   <p>Here are some examples of what this proposal offers.
In these examples, we ignore <code class="highlight"><c- n>std</c-><c- o>::</c-></code> namespace qualification
for anything in our proposal or for <code class="highlight"><c- n>mdspan</c-></code>.
We start with a "hello world" that scales the elements of a 1-D <code class="highlight"><c- n>mdspan</c-></code> by a constant factor, first sequentially, then in parallel.</p>
<pre class="language-c++ highlight">  <c- n>constexpr</c-> <c- b>size_t</c-> <c- n>N</c-> <c- o>=</c-> <c- mi>40</c-><c- p>;</c->
  <c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>double</c-><c- o>></c-> <c- n>x_vec</c-><c- p>(</c-><c- n>N</c-><c- p>);</c->

  <c- n>mdspan</c-> <c- nf>x</c-><c- p>(</c-><c- n>x_vec</c-><c- p>.</c-><c- n>data</c-><c- p>(),</c-> <c- n>N</c-><c- p>);</c->
  <c- k>for</c-><c- p>(</c-><c- b>size_t</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>&lt;</c-> <c- n>N</c-><c- p>;</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c-> <c- p>{</c->
    <c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-> <c- b>double</c-><c- p>(</c-><c- n>i</c-><c- p>);</c->
    <c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-> <c- b>double</c-><c- p>(</c-><c- n>i</c-><c- p>)</c-> <c- o>+</c-> <c- mf>1.0</c-><c- p>;</c->
  <c- p>}</c->

  <c- n>linalg</c-><c- o>::</c-><c- n>scale</c-><c- p>(</c-><c- mf>2.0</c-><c- p>,</c-> <c- n>x</c-><c- p>);</c-> <c- c1>// x = 2.0 * x</c->
  <c- n>linalg</c-><c- o>::</c-><c- n>scale</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>execution</c-><c- o>::</c-><c- n>par_unseq</c-><c- p>,</c-> <c- mf>3.0</c-><c- p>,</c-> <c- n>x</c-><c- p>);</c->
  <c- k>for</c-><c- p>(</c-><c- b>size_t</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>&lt;</c-> <c- n>N</c-><c- p>;</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c-> <c- p>{</c->
    <c- n>assert</c-><c- p>(</c-><c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>==</c-> <c- mf>6.0</c-> <c- o>*</c-> <c- b>double</c-><c- p>(</c-><c- n>i</c-><c- p>));</c->
  <c- p>}</c->
</pre>
   <p>Here is a matrix-vector product example.
It illustrates the <code class="highlight"><c- n>scaled</c-></code> function that makes our interface more concise,
while still permitting the BLAS' performance optimization
of fusing computations with multiplications by a scalar.
It also shows the ability to exploit dimensions known at compile time,
and to mix compile-time and run-time dimensions arbitrarily.</p>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- b>size_t</c-> <c- n>N</c-> <c- o>=</c-> <c- mi>40</c-><c- p>;</c->
<c- n>constexpr</c-> <c- b>size_t</c-> <c- n>M</c-> <c- o>=</c-> <c- mi>20</c-><c- p>;</c->

<c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>double</c-><c- o>></c-> <c- n>A_vec</c-><c- p>(</c-><c- n>N</c-><c- o>*</c-><c- n>M</c-><c- p>);</c->
<c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>double</c-><c- o>></c-> <c- n>x_vec</c-><c- p>(</c-><c- n>M</c-><c- p>);</c->
<c- n>std</c-><c- o>::</c-><c- n>array</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>N</c-><c- o>></c-> <c- n>y_vec</c-><c- p>(</c-><c- n>N</c-><c- p>);</c->

<c- n>mdspan</c-> <c- nf>A</c-><c- p>(</c-><c- n>A_vec</c-><c- p>.</c-><c- n>data</c-><c- p>(),</c-> <c- n>N</c-><c- p>,</c-> <c- n>M</c-><c- p>);</c->
<c- n>mdspan</c-> <c- nf>x</c-><c- p>(</c-><c- n>x_vec</c-><c- p>.</c-><c- n>data</c-><c- p>(),</c-> <c- n>M</c-><c- p>);</c->
<c- n>mdspan</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- n>N</c-><c- o>>></c-> <c- n>y</c-><c- p>(</c-><c- n>y_vec</c-><c- p>.</c-><c- n>data</c-><c- p>());</c->

<c- k>for</c-><c- p>(</c-><c- b>int</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>&lt;</c-> <c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>);</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c-> <c- p>{</c->
  <c- k>for</c-><c- p>(</c-><c- b>int</c-> <c- n>j</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>j</c-> <c- o>&lt;</c-> <c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>);</c-> <c- o>++</c-><c- n>j</c-><c- p>)</c-> <c- p>{</c->
    <c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-> <c- mf>100.0</c-> <c- o>*</c-> <c- n>i</c-> <c- o>+</c-> <c- n>j</c-><c- p>;</c->
  <c- p>}</c->
<c- p>}</c->
<c- k>for</c-><c- p>(</c-><c- b>int</c-> <c- n>j</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>j</c-> <c- o>&lt;</c-> <c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>);</c-> <c- o>++</c-><c- n>j</c-><c- p>)</c-> <c- p>{</c->
  <c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-> <c- mf>1.0</c-> <c- o>*</c-> <c- n>j</c-><c- p>;</c->
<c- p>}</c->
<c- k>for</c-><c- p>(</c-><c- b>int</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>&lt;</c-> <c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>);</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c-> <c- p>{</c->
  <c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-> <c- mf>-1.0</c-> <c- o>*</c-> <c- n>i</c-><c- p>;</c->
<c- p>}</c->

<c- n>linalg</c-><c- o>::</c-><c- n>matrix_vector_product</c-><c- p>(</c-><c- n>A</c-><c- p>,</c-> <c- n>x</c-><c- p>,</c-> <c- n>y</c-><c- p>);</c-> <c- c1>// y = A * x</c->

<c- c1>// y = 0.5 * y + 2 * A * x</c->
<c- n>linalg</c-><c- o>::</c-><c- n>matrix_vector_product</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>execution</c-><c- o>::</c-><c- n>par</c-><c- p>,</c->
  <c- n>linalg</c-><c- o>::</c-><c- n>scaled</c-><c- p>(</c-><c- mf>2.0</c-><c- p>,</c-> <c- n>A</c-><c- p>),</c-> <c- n>x</c-><c- p>,</c->
  <c- n>linalg</c-><c- o>::</c-><c- n>scaled</c-><c- p>(</c-><c- mf>0.5</c-><c- p>,</c-> <c- n>y</c-><c- p>),</c-> <c- n>y</c-><c- p>);</c->
</pre>
   <p>This example illustrates the ability to perform mixed-precision computations,
and the ability to compute on subviews of a matrix or vector
by using <code class="highlight"><c- n>submdspan</c-></code>.</p>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- b>size_t</c-> <c- n>M</c-> <c- o>=</c-> <c- mi>40</c-><c- p>;</c->

<c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>float</c-><c- o>></c-> <c- n>A_vec</c-><c- p>(</c-><c- n>M</c-><c- o>*</c-><c- mi>8</c-><c- o>*</c-><c- mi>4</c-><c- p>);</c->
<c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>double</c-><c- o>></c-> <c- n>x_vec</c-><c- p>(</c-><c- n>M</c-><c- o>*</c-><c- mi>4</c-><c- p>);</c->
<c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>double</c-><c- o>></c-> <c- n>y_vec</c-><c- p>(</c-><c- n>M</c-><c- o>*</c-><c- mi>8</c-><c- p>);</c->

<c- n>mdspan</c-><c- o>&lt;</c-><c- b>float</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- n>dynamic_extent</c-><c- p>,</c-> <c- mi>8</c-><c- p>,</c-> <c- mi>4</c-><c- o>>></c-> <c- n>A</c-><c- p>(</c-><c- n>A_vec</c-><c- p>.</c-><c- n>data</c-><c- p>(),</c-> <c- n>M</c-><c- p>);</c->
<c- n>mdspan</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- mi>4</c-><c- p>,</c-> <c- n>dynamic_extent</c-><c- o>>></c-> <c- n>x</c-><c- p>(</c-><c- n>x_vec</c-><c- p>.</c-><c- n>data</c-><c- p>(),</c-> <c- n>M</c-><c- p>);</c->
<c- n>mdspan</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- n>dynamic_extent</c-><c- p>,</c-> <c- mi>8</c-><c- o>>></c-> <c- n>y</c-><c- p>(</c-><c- n>y_vec</c-><c- p>.</c-><c- n>data</c-><c- p>(),</c-> <c- n>M</c-><c- p>);</c->

<c- k>for</c-><c- p>(</c-><c- b>size_t</c-> <c- n>m</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>m</c-> <c- o>&lt;</c-> <c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>);</c-> <c- o>++</c-><c- n>m</c-><c- p>)</c-> <c- p>{</c->
  <c- k>for</c-><c- p>(</c-><c- b>size_t</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>&lt;</c-> <c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>);</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c-> <c- p>{</c->
    <c- k>for</c-><c- p>(</c-><c- b>size_t</c-> <c- n>j</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>j</c-> <c- o>&lt;</c-> <c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>2</c-><c- p>);</c-> <c- o>++</c-><c- n>j</c-><c- p>)</c-> <c- p>{</c->
      <c- n>A</c-><c- p>[</c-><c- n>m</c-><c- p>,</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-> <c- mf>1000.0</c-> <c- o>*</c-> <c- n>m</c-> <c- o>+</c-> <c- mf>100.0</c-> <c- o>*</c-> <c- n>i</c-> <c- o>+</c-> <c- n>j</c-><c- p>;</c->
    <c- p>}</c->
  <c- p>}</c->
<c- p>}</c->
<c- k>for</c-><c- p>(</c-><c- b>size_t</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>&lt;</c-> <c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>);</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c-> <c- p>{</c->
  <c- k>for</c-><c- p>(</c-><c- b>size_t</c-> <c- n>m</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>m</c-> <c- o>&lt;</c-> <c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>);</c-> <c- o>++</c-><c- n>m</c-><c- p>)</c-> <c- p>{</c->
    <c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>m</c-><c- p>]</c-> <c- o>=</c-> <c- mf>33.</c-> <c- o>*</c-> <c- n>i</c-> <c- o>+</c-> <c- mf>0.33</c-> <c- o>*</c-> <c- n>m</c-><c- p>;</c->
  <c- p>}</c->
<c- p>}</c->
<c- k>for</c-><c- p>(</c-><c- b>size_t</c-> <c- n>m</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>m</c-> <c- o>&lt;</c-> <c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>);</c-> <c- o>++</c-><c- n>m</c-><c- p>)</c-> <c- p>{</c->
  <c- k>for</c-><c- p>(</c-><c- b>size_t</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>&lt;</c-> <c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>);</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c-> <c- p>{</c->
    <c- n>y</c-><c- p>[</c-><c- n>m</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-> <c- mf>33.</c-> <c- o>*</c-> <c- n>m</c-> <c- o>+</c-> <c- mf>0.33</c-> <c- o>*</c-> <c- n>i</c-><c- p>;</c->
  <c- p>}</c->
<c- p>}</c->

<c- k>for</c-><c- p>(</c-><c- b>size_t</c-> <c- n>m</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>m</c-> <c- o>&lt;</c-> <c- n>M</c-><c- p>;</c-> <c- o>++</c-><c- n>m</c-><c- p>)</c-> <c- p>{</c->
  <c- k>auto</c-> <c- n>A_m</c-> <c- o>=</c-> <c- n>submdspan</c-><c- p>(</c-><c- n>A</c-><c- p>,</c-> <c- n>m</c-><c- p>,</c-> <c- n>full_extent</c-><c- p>,</c-> <c- n>full_extent</c-><c- p>);</c->
  <c- k>auto</c-> <c- n>x_m</c-> <c- o>=</c-> <c- n>submdspan</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- n>full_extent</c-><c- p>,</c-> <c- n>m</c-><c- p>);</c->
  <c- k>auto</c-> <c- n>y_m</c-> <c- o>=</c-> <c- n>submdspan</c-><c- p>(</c-><c- n>y</c-><c- p>,</c-> <c- n>m</c-><c- p>,</c-> <c- n>full_extent</c-><c- p>);</c->
  <c- c1>// y_m = A * x_m</c->
  <c- n>linalg</c-><c- o>::</c-><c- n>matrix_vector_product</c-><c- p>(</c-><c- n>A_m</c-><c- p>,</c-> <c- n>x_m</c-><c- p>,</c-> <c- n>y_m</c-><c- p>);</c->
<c- p>}</c->
</pre>
   <h2 class="heading settled" data-level="4" id="overview-of-contents"><span class="secno">4. </span><span class="content">Overview of contents</span><a class="self-link" href="#overview-of-contents"></a></h2>
   <p>Section <a href="#interoperable-with-other-linear-algebra-proposals"><span class="secno">5</span></a> explains how this proposal is interoperable with other linear algebra proposals currently under WG21 review.
In particular, we believe this proposal is complementary to P1385R6,
and the authors of P1385R6 have expressed the same view.</p>
   <p>Section <a href="#why-include-dense-linear-algebra-in-the-c-standard-library"><span class="secno">6</span></a> motivates considering <em>any</em> dense linear algebra proposal for the C++ Standard Library.</p>
   <p>Section <a href="#why-base-a-c-linear-algebra-library-on-the-blas"><span class="secno">7</span></a> shows why we chose the BLAS as a starting point for our proposed library.
The BLAS is an existing standard with decades of use,
a rich set of functions,
and many optimized implementations.</p>
   <p>Section <a href="#criteria-for-including-algorithms"><span class="secno">8</span></a> lists what we consider general criteria for including algorithms in the C++ Standard Library.
We rely on these criteria to justify the algorithms in this proposal.</p>
   <p>Section <a href="#notation-and-conventions"><span class="secno">9</span></a> describes BLAS notation and conventions in C++ terms.
Understanding this will give readers context for algorithms,
and show how our proposed algorithms expand on BLAS functionality.</p>
   <p>Section <a href="#what-we-exclude-from-the-design"><span class="secno">10</span></a> lists functionality that we intentionally exclude from our proposal.
We imitate the BLAS in aiming to be a set of "performance primitives"
on which external libraries or applications
may build a more complete linear algebra solution.</p>
   <p>Section <a href="#design-justification"><span class="secno">11</span></a> elaborates on our design justification.
This section explains</p>
   <ul>
    <li data-md>
     <p>why we use <code class="highlight"><c- n>mdspan</c-></code> to represent matrix and vector parameters;</p>
    <li data-md>
     <p>how we translate the BLAS' Fortran-centric idioms into C++;</p>
    <li data-md>
     <p>how the BLAS' different "matrix types" map to different algorithms,
rather than different <code class="highlight"><c- n>mdspan</c-></code> layouts;</p>
    <li data-md>
     <p>how we express quality-of-implementation recommendations
about avoiding undue overflow and underflow; and</p>
    <li data-md>
     <p>how we impose requirements on algorithms' behavior
and on the various value types that algorithms encounter.</p>
   </ul>
   <p>Section <a href="#future-work"><span class="secno">12</span></a> lists future work, that is, ways future proposals could build on this one.</p>
   <p>Section <a href="#data-structures-and-utilities-borrowed-from-other-proposals"><span class="secno">13</span></a> gives the data structures and utilities from other proposals on which we depend.
In particular, we rely heavily on <code class="highlight"><c- n>mdspan</c-></code> (P0009),
and add custom layouts and accessors.</p>
   <p>Section <a href="#acknowledgments"><span class="secno">14</span></a> credits funding agencies and contributors.</p>
   <p>Section <a href="#references"><span class="secno">15</span></a> is our bibliography.</p>
   <p>Section <a href="#wording"><span class="secno">16</span></a> is where readers will find the normative wording we propose.</p>
   <p>Finally, Section <a href="#examples"><span class="secno">17</span></a> gives some more elaborate examples of linear algebra algorithms that use our proposal.
The examples show how <code class="highlight"><c- n>mdspan</c-></code>'s features let users easily describe "submatrices" with <code class="highlight"><c- n>submdspan</c-></code>.
This integrates naturally with "block" factorizations of matrices.
The resulting notation is concise, yet still computes in place,
without unnecessary copies of any part of the matrix.</p>
   <p>Here is a table that maps between Reference BLAS function name,
and algorithm or function name in our proposal.
The mapping is not always one to one.
"N/A" in the "BLAS name(s)" field means that the function is not in the BLAS.</p>
   <table>
    <tbody>
     <tr>
      <th>BLAS name(s)
      <th>Our name(s)
     <tr>
      <td>xLARTG
      <td><code class="highlight"><c- n>givens_rotation_setup</c-></code>
     <tr>
      <td>xROT
      <td><code class="highlight"><c- n>givens_rotation_apply</c-></code>
     <tr>
      <td>xSWAP
      <td><code class="highlight"><c- n>swap_elements</c-></code>
     <tr>
      <td>xSCAL
      <td><code class="highlight"><c- n>scale</c-></code>, <code class="highlight"><c- n>scaled</c-></code>
     <tr>
      <td>xCOPY
      <td><code class="highlight"><c- n>copy</c-></code>
     <tr>
      <td>xAXPY
      <td><code class="highlight"><c- n>add</c-></code>, <code class="highlight"><c- n>scaled</c-></code>
     <tr>
      <td>xDOT, xDOTU
      <td><code class="highlight"><c- n>dot</c-></code>
     <tr>
      <td>xDOTC
      <td><code class="highlight"><c- n>dotc</c-></code>
     <tr>
      <td>N/A
      <td><code class="highlight"><c- n>vector_sum_of_squares</c-></code>
     <tr>
      <td>xNRM2
      <td><code class="highlight"><c- n>vector_norm2</c-></code>
     <tr>
      <td>xASUM
      <td><code class="highlight"><c- n>vector_abs_sum</c-></code>
     <tr>
      <td>xIAMAX
      <td><code class="highlight"><c- n>idx_abs_max</c-></code>
     <tr>
      <td>N/A
      <td><code class="highlight"><c- n>matrix_frob_norm</c-></code>
     <tr>
      <td>N/A
      <td><code class="highlight"><c- n>matrix_one_norm</c-></code>
     <tr>
      <td>N/A
      <td><code class="highlight"><c- n>matrix_inf_norm</c-></code>
     <tr>
      <td>xGEMV
      <td><code class="highlight"><c- n>matrix_vector_product</c-></code>
     <tr>
      <td>xSYMV
      <td><code class="highlight"><c- n>symmetric_matrix_vector_product</c-></code>
     <tr>
      <td>xHEMV
      <td><code class="highlight"><c- n>hermitian_matrix_vector_product</c-></code>
     <tr>
      <td>xTRMV
      <td><code class="highlight"><c- n>triangular_matrix_vector_product</c-></code>
     <tr>
      <td>xTRSV
      <td><code class="highlight"><c- n>triangular_matrix_vector_solve</c-></code>
     <tr>
      <td>xGER, xGERU
      <td><code class="highlight"><c- n>matrix_rank_1_update</c-></code>
     <tr>
      <td>xGERC
      <td><code class="highlight"><c- n>matrix_rank_1_update_c</c-></code>
     <tr>
      <td>xSYR
      <td><code class="highlight"><c- n>symmetric_matrix_rank_1_update</c-></code>
     <tr>
      <td>xHER
      <td><code class="highlight"><c- n>hermitian_matrix_rank_1_update</c-></code>
     <tr>
      <td>xSYR2
      <td><code class="highlight"><c- n>symmetric_matrix_rank_2_update</c-></code>
     <tr>
      <td>xHER2
      <td><code class="highlight"><c- n>hermitian_matrix_rank_2_update</c-></code>
     <tr>
      <td>xGEMM
      <td><code class="highlight"><c- n>matrix_product</c-></code>
     <tr>
      <td>xSYMM
      <td><code class="highlight"><c- n>symmetric_matrix_</c-><c- p>{</c-><c- n>left</c-><c- p>,</c-><c- n>right</c-><c- p>}</c-><c- n>_product</c-></code>
     <tr>
      <td>xHEMM
      <td><code class="highlight"><c- n>hermitian_matrix_</c-><c- p>{</c-><c- n>left</c-><c- p>,</c-><c- n>right</c-><c- p>}</c-><c- n>_product</c-></code>
     <tr>
      <td>xTRMM
      <td><code class="highlight"><c- n>triangular_matrix_</c-><c- p>{</c-><c- n>left</c-><c- p>,</c-><c- n>right</c-><c- p>}</c-><c- n>_product</c-></code>
     <tr>
      <td>xSYRK
      <td><code class="highlight"><c- n>symmetric_matrix_rank_k_update</c-></code>
     <tr>
      <td>xHERK
      <td><code class="highlight"><c- n>hermitian_matrix_rank_k_update</c-></code>
     <tr>
      <td>xSYR2K
      <td><code class="highlight"><c- n>symmetric_matrix_rank_2k_update</c-></code>
     <tr>
      <td>xHER2K
      <td><code class="highlight"><c- n>hermitian_matrix_rank_2k_update</c-></code>
     <tr>
      <td>xTRSM
      <td><code class="highlight"><c- n>triangular_matrix_matrix_</c-><c- p>{</c-><c- n>left</c-><c- p>,</c-><c- n>right</c-><c- p>}</c-><c- n>_solve</c-></code>
   </table>
   <h2 class="heading settled" data-level="5" id="interoperable-with-other-linear-algebra-proposals"><span class="secno">5. </span><span class="content">Interoperable with other linear algebra proposals</span><a class="self-link" href="#interoperable-with-other-linear-algebra-proposals"></a></h2>
   <p>We believe this proposal is complementary to P1385R6,
a proposal for a C++ Standard linear algebra library
that introduces matrix and vector classes with overloaded arithmetic operators.
The P1385 authors and we have expressed together in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1891r0.pdf">a joint paper, P1891</a>,
that P1673 and P1385 "are orthogonal.
They are not competing papers; ...
there is no overlap of functionality."</p>
   <p>Many of us have had experience using and implementing
matrix and vector operator arithmetic libraries like what P1385 proposes.
We designed P1673 in part as a natural foundation or implementation layer for such libraries.
Our view is that a free function interface like P1673’s
clearly separates algorithms from data structures,
and more naturally allows for a richer set of operations such as what the BLAS provides.
P1674 explains why we think our proposal is a minimal C++ "respelling" of the BLAS.</p>
   <p>A natural extension of the present proposal would include
accepting P1385’s matrix and vector objects as input
for the algorithms proposed here.
A straightforward way to do that would be for P1385’s matrix and vector objects
to make views of their data available as <code class="highlight"><c- n>mdspan</c-></code>.</p>
   <h2 class="heading settled" data-level="6" id="why-include-dense-linear-algebra-in-the-c-standard-library"><span class="secno">6. </span><span class="content">Why include dense linear algebra in the C++ Standard Library?</span><a class="self-link" href="#why-include-dense-linear-algebra-in-the-c-standard-library"></a></h2>
   <ol>
    <li data-md>
     <p>"Direction for ISO C++" (P0939R4)
explicitly calls out "Linear Algebra" as a potential priority for C++23.</p>
    <li data-md>
     <p>C++ applications in "important application areas" (see P0939R4)
have depended on linear algebra for a long time.</p>
    <li data-md>
     <p>Linear algebra is like <code class="highlight"><c- n>sort</c-></code>: obvious algorithms are slow, and the
fastest implementations call for hardware-specific tuning.</p>
    <li data-md>
     <p>Dense linear algebra is core functionality for most of linear
algebra, and can also serve as a building block for tensor
operations.</p>
    <li data-md>
     <p>The C++ Standard Library includes plenty of "mathematical
functions."  Linear algebra operations like matrix-matrix multiply
are at least as broadly useful.</p>
    <li data-md>
     <p>The set of linear algebra operations in this proposal are derived
from a well-established, standard set of algorithms that has
changed very little in decades.  It is one of the strongest
possible examples of standardizing existing practice that anyone
could bring to C++.</p>
    <li data-md>
     <p>This proposal follows in the footsteps of many recent successful
incorporations of existing standards into C++, including the UTC
and TAI standard definitions from the International
Telecommunications Union, the time zone database standard from the
International Assigned Numbers Authority, and the ongoing effort to
integrate the ISO unicode standard.</p>
   </ol>
   <p>Linear algebra has had wide use in C++ applications for nearly three
decades (see P1417R0 for a historical survey).
For much of that time, many third-party C++ libraries for linear
algebra have been available.  Many different subject areas depend on
linear algebra, including machine learning, data mining, web search,
statistics, computer graphics, medical imaging, geolocation and
mapping, engineering, and physics-based simulations.</p>
   <p>"Directions for ISO C++" (P0939R4)
not only lists "Linear Algebra" explicitly as a potential C++23 priority,
it also offers the following
in support of adding linear algebra to the C++ Standard Library.</p>
   <ul>
    <li data-md>
     <p>P0939R4 calls out "Support for demanding applications"
in "important application areas,
such as medical, finance, automotive, and games
(e.g., key libraries...)" as an "area of general concern" that "we
should not ignore."  All of these areas depend on linear algebra.</p>
    <li data-md>
     <p>"Is my proposal essential for some important application domain?"
Many large and small private companies, science and engineering
laboratories, and academics in many different fields all depend on
linear algebra.</p>
    <li data-md>
     <p>"We need better support for modern hardware": Modern hardware spends
many of its cycles in linear algebra.  For decades, hardware
vendors, some represented at WG21 meetings, have provided and
continue to provide features specifically to accelerate linear
algebra operations.  Some of them even implement specific linear
algebra operations directly in hardware.  Examples include NVIDIA’s <a href="https://www.nvidia.com/en-us/data-center/tensorcore/">Tensor Cores</a> and Cerebras' <a href="https://www.cerebras.net/product/#chip">Wafer Scale
Engine</a>.  Several large
computer system vendors offer optimized linear algebra libraries
based on or closely resembling the BLAS; these include AMD’s BLIS,
ARM’s Performance Libraries, Cray’s LibSci, Intel’s Math Kernel
Library (MKL), IBM’s Engineering and Scientific Subroutine Library
(ESSL), and NVIDIA’s cuBLAS.</p>
   </ul>
   <p>Obvious algorithms for some linear algebra operations like dense
matrix-matrix multiply are asymptotically slower than less-obvious
algorithms.  (Please refer to a survey one of us coauthored, <a href="https://doi.org/10.1017/S0962492914000038">"Communication lower bounds and optimal algorithms for numerical
linear algebra."</a>)
Furthermore, writing the fastest dense matrix-matrix multiply depends
on details of a specific computer architecture.  This makes such
operations comparable to <code class="highlight"><c- n>sort</c-></code> in the C++ Standard Library: worth
standardizing, so that Standard Library implementers can get them
right and hardware vendors can optimize them.  In fact, almost all C++
linear algebra libraries end up calling non-C++ implementations of
these algorithms, especially the implementations in optimized BLAS
libraries (see below).  In this respect, linear algebra is also
analogous to standard library features like <code class="highlight"><c- n>random_device</c-></code>: often
implemented directly in assembly or even with special hardware, and
thus an essential component of allowing no room for another language
"below" C++ (see P0939R4)
and Stroustrup’s "The Design and Evolution of C++").</p>
   <p>Dense linear algebra is the core component of most algorithms and
applications that use linear algebra, and the component that is most
widely shared over different application areas.  For example, tensor
computations end up spending most of their time in optimized dense
linear algebra functions.  Sparse matrix computations get best
performance when they spend as much time as possible in dense linear
algebra.</p>
   <p>The C++ Standard Library includes many "mathematical special
functions" (<strong>[sf.cmath]</strong>), like incomplete elliptic integrals,
Bessel functions, and other polynomials and functions named after
various mathematicians.  Any of them comes with its own theory and set
of applications for which robust and accurate implementations are
indispensible.  We think that linear algebra operations are at least
as broadly useful, and in many cases significantly more so.</p>
   <h2 class="heading settled" data-level="7" id="why-base-a-c-linear-algebra-library-on-the-blas"><span class="secno">7. </span><span class="content">Why base a C++ linear algebra library on the BLAS?</span><a class="self-link" href="#why-base-a-c-linear-algebra-library-on-the-blas"></a></h2>
   <ol>
    <li data-md>
     <p>The BLAS is a standard that codifies decades of existing practice.</p>
    <li data-md>
     <p>The BLAS separates "performance primitives" for hardware
experts to tune, from mathematical operations that rely on those
primitives for good performance.</p>
    <li data-md>
     <p>Benchmarks reward hardware and system vendors for providing
optimized BLAS implementations.</p>
    <li data-md>
     <p>Writing a fast BLAS implementation for common element types is
nontrivial, but well understood.</p>
    <li data-md>
     <p>Optimized third-party BLAS implementations with liberal software
licenses exist.</p>
    <li data-md>
     <p>Building a C++ interface on top of the BLAS is a straightforward
exercise, but has pitfalls for unaware developers.</p>
   </ol>
   <p>Linear algebra has had a cross-language standard, the Basic Linear
Algebra Subroutines (BLAS), since 2002.  The Standard came out of a <a href="http://www.netlib.org/blas/blast-forum/">standardization process</a> that started in 1995 and held meetings three times a year until 1999.
Participants in the process came from industry, academia, and
government research laboratories.  The dense linear algebra subset of
the BLAS codifies forty years of evolving practice, and has existed in
recognizable form since 1990 (see P1417R0).</p>
   <p>The BLAS interface was specifically designed as the distillation of
the "computer science" / performance-oriented parts of linear algebra
algorithms.  It cleanly separates operations most critical for
performance, from operations whose implementation takes expertise in
mathematics and rounding-error analysis.  This gives vendors
opportunities to add value, without asking for expertise outside the
typical required skill set of a Standard Library implementer.</p>
   <p>Well-established benchmarks such as the <a href="https://www.top500.org/project/linpack/">LINPACK
benchmark</a> reward computer
hardware vendors for optimizing their BLAS implementations.  Thus,
many vendors provide an optimized BLAS library for their computer
architectures.  Writing fast BLAS-like operations is not trivial, and
depends on computer architecture.  However, it is a well-understood
problem whose solutions could be parameterized for a variety of
computer architectures.  See, for example, <a href="https://doi.org/10.1145/1356052.1356053">Goto and van de Geijn
2008</a>.  There are optimized
third-party BLAS implementations for common architectures, like <a href="http://math-atlas.sourceforge.net/">ATLAS</a> and <a href="https://www.tacc.utexas.edu/research-development/tacc-software/gotoblas2">GotoBLAS</a>.
A (slow but correct) <a href="http://www.netlib.org/blas/#_reference_blas_version_3_8_0">reference implementation of the BLAS</a> exists and it has a liberal software license for easy reuse.</p>
   <p>We have experience in the exercise of wrapping a C or Fortran BLAS
implementation for use in portable C++ libraries.  We describe this
exercise in detail in our paper <a href="https://wg21.link/p1674">"Evolving a Standard C++ Linear
Algebra Library from the BLAS" (P1674)</a>.  It
is straightforward for vendors, but has pitfalls for developers.  For
example, Fortran’s application binary interface (ABI) differs across
platforms in ways that can cause run-time errors (even incorrect
results, not just crashing).  Historical examples of vendors' C BLAS
implementations have also had ABI issues that required work-arounds.
This dependence on ABI details makes availability in a standard C++
library valuable.</p>
   <h2 class="heading settled" data-level="8" id="criteria-for-including-algorithms"><span class="secno">8. </span><span class="content">Criteria for including algorithms</span><a class="self-link" href="#criteria-for-including-algorithms"></a></h2>
   <p>We include algorithms in our proposal based on the following criteria,
ordered by decreasing importance.
Many of our algorithms satisfy multiple criteria.</p>
   <ol>
    <li data-md>
     <p>Getting the desired asymptotic run time is nontrivial</p>
    <li data-md>
     <p>Opportunity for vendors to provide hardware-specific optimizations</p>
    <li data-md>
     <p>Opportunity for vendors to provide quality-of-implementation improvements,
especially relating to accuracy or reproducibility
with respect to floating-point rounding error</p>
    <li data-md>
     <p>User convenience (familiar name, or tedious to implement)</p>
   </ol>
   <p>Regarding (1), "nontrivial" means "at least for novices to the field."
Dense matrix-matrix multiply is a good example.
Getting close to the asymptotic lower bound on the number of memory reads and writes
matters a lot for performance, and calls for a nonintuitive loop reordering.
An analogy to the current C++ Standard Library is <code class="highlight"><c- n>sort</c-></code>,
where intuitive algorithms that many humans use are not asymptotically optimal.</p>
   <p>Regarding (2), a good example is copying multidimensional arrays.
The <a href="github.com/kokkos/kokkos">Kokkos library</a> spends about 2500 lines of code on multidimensional array copy,
yet still relies on system libraries for low-level optimizations.
An analogy to the current C++ Standard Library is <code class="highlight"><c- n>copy</c-></code> or even <code class="highlight"><c- n>memcpy</c-></code>.</p>
   <p>Regarding (3), accurate floating-point summation is nontrivial.
Well-meaning compiler optimizations might defeat even simple technqiues,
like compensated summation.
The most obvious way to compute a vector’s Euclidean norm
(square root of sum of squares) can cause overflow or underflow,
even when the exact answer is much smaller than the overflow threshold,
or larger than the underflow threshold.
Some users care deeply about sums, even parallel sums,
that always get the same answer, despite rounding error.
This can help debugging, for example.
It is possible to make floating-point sums completely independent
of parallel evaluation order.
See e.g., the <a href="https://bebop.cs.berkeley.edu/reproblas/">ReproBLAS</a> effort.
Naming these algorithms and providing <code class="highlight"><c- n>ExecutionPolicy</c-></code> customization hooks
gives vendors a chance to provide these improvements.
An analogy to the current C++ Standard Library is <code class="highlight"><c- n>hypot</c-></code>,
whose language in the C++ Standard alludes to the tighter POSIX requirements.</p>
   <p>Regarding (4), the C++ Standard Library is not entirely minimalist.
One example is <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>string</c-><c- o>::</c-><c- n>contains</c-></code>.
Existing Standard Library algorithms already offered this functionality,
but a member <code class="highlight"><c- n>contains</c-></code> function is easy for novices to find and use,
and avoids the tedium of comparing the result of <code class="highlight"><c- n>find</c-></code> to <code class="highlight"><c- n>npos</c-></code>.</p>
   <p>The BLAS exists mainly for the first two reasons.
It includes functions that were nontrivial for compilers to optimize in its time,
like scaled elementwise vector sums,
as well as functions that generally require human effort to optimize,
like matrix-matrix multiply.</p>
   <h2 class="heading settled" data-level="9" id="notation-and-conventions"><span class="secno">9. </span><span class="content">Notation and conventions</span><a class="self-link" href="#notation-and-conventions"></a></h2>
   <h3 class="heading settled" data-level="9.1" id="the-blas-uses-fortran-terms"><span class="secno">9.1. </span><span class="content">The BLAS uses Fortran terms</span><a class="self-link" href="#the-blas-uses-fortran-terms"></a></h3>
   <p>The BLAS' "native" language is Fortran.  It has a C binding as well,
but the BLAS Standard and documentation use Fortran terms.  Where
applicable, we will call out relevant Fortran terms and highlight
possibly confusing differences with corresponding C++ ideas.  Our
paper P1674R0 ("Evolving a Standard C++ Linear Algebra Library from
the BLAS") goes into more detail on these issues.</p>
   <h3 class="heading settled" data-level="9.2" id="we-call-subroutines-functions"><span class="secno">9.2. </span><span class="content">We call "subroutines" functions</span><a class="self-link" href="#we-call-subroutines-functions"></a></h3>
   <p>Like Fortran, the BLAS distinguishes between functions that return a
value, and subroutines that do not return a value.  In what follows,
we will refer to both as "BLAS functions" or "functions."</p>
   <h3 class="heading settled" data-level="9.3" id="element-types-and-blas-function-name-prefix"><span class="secno">9.3. </span><span class="content">Element types and BLAS function name prefix</span><a class="self-link" href="#element-types-and-blas-function-name-prefix"></a></h3>
   <p>The BLAS implements functionality for four different matrix, vector,
or scalar element types:</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>REAL</c-></code> (<code class="highlight"><c- b>float</c-></code> in C++ terms)</p>
    <li data-md>
     <p><code class="highlight"><c- n>DOUBLE</c-> <c- n>PRECISION</c-></code> (<code class="highlight"><c- b>double</c-></code> in C++ terms)</p>
    <li data-md>
     <p><code class="highlight"><c- n>COMPLEX</c-></code> (<code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- b>float</c-><c- o>></c-></code> in C++ terms)</p>
    <li data-md>
     <p><code class="highlight"><c- n>DOUBLE</c-> <c- n>COMPLEX</c-></code> (<code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- b>double</c-><c- o>></c-></code> in C++ terms)</p>
   </ul>
   <p>The BLAS' Fortran 77 binding uses a function name prefix to
distinguish functions based on element type:</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>S</c-></code> for <code class="highlight"><c- n>REAL</c-></code> ("single")</p>
    <li data-md>
     <p><code class="highlight"><c- n>D</c-></code> for <code class="highlight"><c- n>DOUBLE</c-> <c- n>PRECISION</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>C</c-></code> for <code class="highlight"><c- n>COMPLEX</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>Z</c-></code> for <code class="highlight"><c- n>DOUBLE</c-> <c- n>COMPLEX</c-></code></p>
   </ul>
   <p>For example, the four BLAS functions <code class="highlight"><c- n>SAXPY</c-></code>, <code class="highlight"><c- n>DAXPY</c-></code>, <code class="highlight"><c- n>CAXPY</c-></code>, and <code class="highlight"><c- n>ZAXPY</c-></code> all perform the vector update <code class="highlight"><c- n>Y</c-> <c- o>=</c-> <c- n>Y</c-> <c- o>+</c-> <c- n>ALPHA</c-><c- o>*</c-><c- n>X</c-></code> for vectors <code class="highlight"><c- n>X</c-></code> and <code class="highlight"><c- n>Y</c-></code> and scalar <code class="highlight"><c- n>ALPHA</c-></code>, but for different vector and scalar
element types.</p>
   <p>The convention is to refer to all of these functions together as <code class="highlight"><c- n>xAXPY</c-></code>.  In general, a lower-case <code class="highlight"><c- n>x</c-></code> is a placeholder for all data
type prefixes that the BLAS provides.  For most functions, the <code class="highlight"><c- n>x</c-></code> is
a prefix, but for a few functions like <code class="highlight"><c- n>IxAMAX</c-></code>, the data type
"prefix" is not the first letter of the function name.  (<code class="highlight"><c- n>IxAMAX</c-></code> is a
Fortran function that returns <code class="highlight"><c- n>INTEGER</c-></code>, and therefore follows the old
Fortran implicit naming rule that integers start with <code class="highlight"><c- n>I</c-></code>, <code class="highlight"><c- n>J</c-></code>, etc.)</p>
   <p>Not all BLAS functions exist for all four data types.  These come in
three categories:</p>
   <ol>
    <li data-md>
     <p>The BLAS provides only real-arithmetic (<code class="highlight"><c- n>S</c-></code> and <code class="highlight"><c- n>D</c-></code>) versions of
the function, since the function only makes mathematical sense in
real arithmetic.</p>
    <li data-md>
     <p>The complex-arithmetic versions perform a slightly different
mathematical operation than the real-arithmetic versions, so
they have a different base name.</p>
    <li data-md>
     <p>The complex-arithmetic versions offer a choice between
nonconjugated or conjugated operations.</p>
   </ol>
   <p>As an example of the second category, the BLAS functions <code class="highlight"><c- n>SASUM</c-></code> and <code class="highlight"><c- n>DASUM</c-></code> compute the sums of absolute values of a vector’s elements.
Their complex counterparts <code class="highlight"><c- n>CSASUM</c-></code> and <code class="highlight"><c- n>DZASUM</c-></code> compute the sums of
absolute values of real and imaginary components of a vector <code class="highlight"><c- n>v</c-></code>, that
is, the sum of <code class="highlight"><c- n>abs</c-><c- p>(</c-><c- n>real</c-><c- p>(</c-><c- n>v</c-><c- p>[</c-><c- n>i</c-><c- p>]))</c-> <c- o>+</c-> <c- n>abs</c-><c- p>(</c-><c- n>imag</c-><c- p>(</c-><c- n>v</c-><c- p>[</c-><c- n>i</c-><c- p>]))</c-></code> for all <code class="highlight"><c- n>i</c-></code> in the
domain of <code class="highlight"><c- n>v</c-></code>.  The latter operation is still useful as a vector norm,
but it requires fewer arithmetic operations.</p>
   <p>Examples of the third category include the following:</p>
   <ul>
    <li data-md>
     <p>nonconjugated dot product <code class="highlight"><c- n>xDOTU</c-></code> and conjugated dot product <code class="highlight"><c- n>xDOTC</c-></code>; and</p>
    <li data-md>
     <p>rank-1 symmetric (<code class="highlight"><c- n>xGERU</c-></code>) vs. Hermitian (<code class="highlight"><c- n>xGERC</c-></code>) matrix update.</p>
   </ul>
   <p>The conjugate transpose and the (nonconjugated) transpose are the
same operation in real arithmetic (if one considers real arithmetic
embedded in complex arithmetic), but differ in complex arithmetic.
Different applications have different reasons to want either.  The C++
Standard includes complex numbers, so a Standard linear algebra
library needs to respect the mathematical structures that go along
with complex numbers.</p>
   <h2 class="heading settled" data-level="10" id="what-we-exclude-from-the-design"><span class="secno">10. </span><span class="content">What we exclude from the design</span><a class="self-link" href="#what-we-exclude-from-the-design"></a></h2>
   <h3 class="heading settled" data-level="10.1" id="most-functions-not-in-the-reference-blas"><span class="secno">10.1. </span><span class="content">Most functions not in the Reference BLAS</span><a class="self-link" href="#most-functions-not-in-the-reference-blas"></a></h3>
   <p>The BLAS Standard includes functionality that appears neither in the <a href="http://www.netlib.org/lapack/explore-html/d1/df9/group__blas.html">Reference BLAS</a> library, nor in the classic BLAS "level" 1, 2, and 3 papers.  (For
history of the BLAS "levels" and a bibliography, see P1417R0.
For a paper describing functions not in the Reference BLAS,
see "An updated set of basic linear algebra subprograms (BLAS),"
listed in "Other references" below.)
For example, the BLAS Standard has</p>
   <ul>
    <li data-md>
     <p>several new dense functions, like a fused vector update and dot
product;</p>
    <li data-md>
     <p>sparse linear algebra functions, like sparse matrix-vector multiply
and an interface for constructing sparse matrices; and</p>
    <li data-md>
     <p>extended- and mixed-precision dense functions (though we subsume
some of their functionality; see below).</p>
   </ul>
   <p>Our proposal only includes core Reference BLAS functionality, for the
following reasons:</p>
   <ol>
    <li data-md>
     <p>Vendors who implement a new component of the C++ Standard Library
will want to see and test against an existing reference
implementation.</p>
    <li data-md>
     <p>Many applications that use sparse linear algebra also use dense,
but not vice versa.</p>
    <li data-md>
     <p>The Sparse BLAS interface is a stateful interface that is not
consistent with the dense BLAS, and would need more extensive
redesign to translate into a modern C++ idiom.
See discussion in P1417R0.</p>
    <li data-md>
     <p>Our proposal subsumes some dense mixed-precision functionality (see
below).</p>
   </ol>
   <p>We have included vector sum-of-squares and matrix norms as exceptions,
for the same reason that we include vector 2-norm:
to expose hooks for quality-of-implementation improvements
that avoid underflow or overflow when computing with floating-point values.</p>
   <h3 class="heading settled" data-level="10.2" id="lapack-or-related-functionality"><span class="secno">10.2. </span><span class="content">LAPACK or related functionality</span><a class="self-link" href="#lapack-or-related-functionality"></a></h3>
   <p>The <a href="http://www.netlib.org/lapack/">LAPACK</a> Fortran library implements
solvers for the following classes of mathematical problems:</p>
   <ul>
    <li data-md>
     <p>linear systems,</p>
    <li data-md>
     <p>linear least-squares problems, and</p>
    <li data-md>
     <p>eigenvalue and singular value problems.</p>
   </ul>
   <p>It also provides matrix factorizations and related linear algebra
operations.  LAPACK deliberately relies on the BLAS for good
performance; in fact, LAPACK and the BLAS were designed together.  See
history presented in P1417R0.</p>
   <p>Several C++ libraries provide slices of LAPACK functionality.  Here is
a brief, noninclusive list, in alphabetical order, of some libraries
actively being maintained:</p>
   <ul>
    <li data-md>
     <p><a href="http://arma.sourceforge.net/">Armadillo</a>,</p>
    <li data-md>
     <p><a href="https://github.com/boostorg/ublas">Boost.uBLAS</a>,</p>
    <li data-md>
     <p><a href="http://eigen.tuxfamily.org/index.php?title=Main_Page">Eigen</a>,</p>
    <li data-md>
     <p><a href="http://www.simunova.com/de/mtl4/">Matrix Template Library</a>, and</p>
    <li data-md>
     <p><a href="https://github.com/trilinos/Trilinos/">Trilinos</a>.</p>
   </ul>
   <p><a href="https://wg21.link/p1417r0">P1417R0</a> gives some history of C++ linear
algebra libraries.  The authors of this proposal have <a href="https://www.icl.utk.edu/files/publications/2017/icl-utk-1031-2017.pdf">designed</a>, <a href="https://github.com/kokkos/kokkos-kernels">written</a>, and <a href="https://github.com/trilinos/Trilinos/tree/master/packages/teuchos/numerics/src">maintained</a> LAPACK wrappers in C++.  Some authors have LAPACK founders as PhD
advisors.  Nevertheless, we have excluded LAPACK-like functionality
from this proposal, for the following reasons:</p>
   <ol>
    <li data-md>
     <p>LAPACK is a Fortran library, unlike the BLAS, which is a
multilanguage standard.</p>
    <li data-md>
     <p>We intend to support more general element types, beyond the four
that LAPACK supports.  It’s much more straightforward to make a C++
BLAS work for general element types, than to make LAPACK algorithms
work generically.</p>
   </ol>
   <p>First, unlike the BLAS, LAPACK is a Fortran library, not a standard.
LAPACK was developed concurrently with the "level 3" BLAS functions,
and the two projects share contributors.  Nevertheless, only the BLAS
and not LAPACK got standardized.  Some vendors supply LAPACK
implementations with some optimized functions, but most
implementations likely depend heavily on "reference" LAPACK.  There
have been a few efforts by LAPACK contributors to develop C++ LAPACK
bindings, from <a href="https://math.nist.gov/lapack++/">Lapack++</a> in
pre-templates C++ circa 1993, to the recent <a href="https://www.icl.utk.edu/files/publications/2017/icl-utk-1031-2017.pdf">"C++ API for BLAS and
LAPACK"</a>.
(The latter shares coauthors with this proposal.)  However, these are
still just C++ bindings to a Fortran library.  This means that if
vendors had to supply C++ functionality equivalent to LAPACK, they
would either need to start with a Fortran compiler, or would need to
invest a lot of effort in a C++ reimplementation.  Mechanical
translation from Fortran to C++ introduces risk, because many LAPACK
functions depend critically on details of floating-point arithmetic
behavior.</p>
   <p>Second, we intend to permit use of matrix or vector element types
other than just the four types that the BLAS and LAPACK support.  This
includes "short" floating-point types, fixed-point types, integers,
and user-defined arithmetic types.  Doing this is easier for BLAS-like
operations than for the much more complicated numerical algorithms in
LAPACK.  LAPACK strives for a "generic" design (see Jack Dongarra
interview summary in P1417R0), but only supports
two real floating-point types and two complex floating-point types.
Directly translating LAPACK source code into a "generic" version could
lead to pitfalls.  Many LAPACK algorithms only make sense for number
systems that aim to approximate real numbers (or their complex
extentions).  Some LAPACK functions output error bounds that rely on
properties of floating-point arithmetic.</p>
   <p>For these reasons, we have left LAPACK-like functionality for future
work.  It would be natural for a future LAPACK-like C++ library to
build on our proposal.</p>
   <h3 class="heading settled" data-level="10.3" id="extended-precision-blas"><span class="secno">10.3. </span><span class="content">Extended-precision BLAS</span><a class="self-link" href="#extended-precision-blas"></a></h3>
   <p>Our interface subsumes some functionality of the Mixed-Precision BLAS
specification (Chapter 4 of the BLAS Standard).  For example, users
may multiply two 16-bit floating-point matrices (assuming that a
16-bit floating-point type exists) and accumulate into a 32-bit
floating-point matrix, just by providing a 32-bit floating-point
matrix as output.  Users may specify the precision of a dot product
result.  If it is greater than the input vectors' element type
precisions (e.g., <code class="highlight"><c- b>double</c-></code> vs. <code class="highlight"><c- b>float</c-></code>), then this effectively
performs accumulation in higher precision.  Our proposal imposes
semantic requirements on some functions, like <code class="highlight"><c- n>vector_norm2</c-></code>, to
behave in this way.</p>
   <p>However, we do not include the "Extended-Precision BLAS" in this
proposal.  The BLAS Standard lets callers decide at run time whether
to use extended precision floating-point arithmetic for internal
evaluations.  We could support this feature at a later time.
Implementations of our interface also have the freedom to use more
accurate evaluation methods than typical BLAS implementations.  For
example, it is possible to make floating-point sums completely <a href="https://bebop.cs.berkeley.edu/reproblas/">independent of parallel evaluation
order</a>.</p>
   <h3 class="heading settled" data-level="10.4" id="arithmetic-operators-and-associated-expression-templates"><span class="secno">10.4. </span><span class="content">Arithmetic operators and associated expression templates</span><a class="self-link" href="#arithmetic-operators-and-associated-expression-templates"></a></h3>
   <p>Our proposal omits arithmetic operators on matrices and vectors.
We do so for the following reasons:</p>
   <ol>
    <li data-md>
     <p>We propose a low-level, minimal interface.</p>
    <li data-md>
     <p><code class="highlight"><c- k>operator</c-><c- o>*</c-></code> could have multiple meanings for matrices and vectors.
Should it mean elementwise product (like <code class="highlight"><c- n>valarray</c-></code>) or matrix
product?  Should libraries reinterpret "vector times vector" as a
dot product (row vector times column vector)?  We prefer to let a
higher-level library decide this, and make everything explicit at
our lower level.</p>
    <li data-md>
     <p>Arithmetic operators require defining the element type of the
vector or matrix returned by an expression.  Functions let users
specify this explicitly, and even let users use different output
types for the same input types in different expressions.</p>
    <li data-md>
     <p>Arithmetic operators may require allocation of temporary matrix or
vector storage.  This prevents use of nonowning data structures.</p>
    <li data-md>
     <p>Arithmetic operators strongly suggest expression templates.  These
introduce problems such as dangling references and aliasing.</p>
   </ol>
   <p>Our goal is to propose a low-level interface.  Other libraries, such
as that proposed by <a href="https://wg21.link/p1385r6">P1385R6</a>, could use our
interface to implement overloaded arithmetic for matrices and vectors.
A constrained, function-based, BLAS-like
interface builds incrementally on the many years of BLAS experience.</p>
   <p>Arithmetic operators on matrices and vectors would require the
library, not necessarily the user, to specify the element type of an
expression’s result.  This gets tricky if the terms have mixed element
types.  For example, what should the element type of the result of the
vector sum <code class="highlight"><c- n>x</c-> <c- o>+</c-> <c- n>y</c-></code> be, if <code class="highlight"><c- n>x</c-></code> has element type <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- b>float</c-><c- o>></c-></code> and <code class="highlight"><c- n>y</c-></code> has element type <code class="highlight"><c- b>double</c-></code>?  It’s tempting to use <code class="highlight"><c- n>common_type_t</c-></code>,
but <code class="highlight"><c- n>common_type_t</c-><c- o>&lt;</c-><c- n>complex</c-><c- o>&lt;</c-><c- b>float</c-><c- o>></c-><c- p>,</c-> <c- b>double</c-><c- o>></c-></code> is <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- b>float</c-><c- o>></c-></code>.  This
loses precision.  Some users may want <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- b>double</c-><c- o>></c-></code>; others may
want <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- b>long</c-> <c- b>double</c-><c- o>></c-></code> or something else, and others may want to
choose different types in the same program.</p>
   <p>P1385R6 lets users customize the return type
of such arithmetic expressions.  However, different algorithms may
call for the same expression with the same inputs to have different
output types.  For example, iterative refinement of linear systems <code class="highlight"><c- n>Ax</c-><c- o>=</c-><c- n>b</c-></code> can work either with an extended-precision intermediate
residual vector <code class="highlight"><c- n>r</c-> <c- o>=</c-> <c- n>b</c-> <c- o>-</c-> <c- n>A</c-><c- o>*</c-><c- n>x</c-></code>, or with a residual vector that has the
same precision as the input linear system.  Each choice produces a
different algorithm with different convergence characteristics,
per-iteration run time, and memory requirements.  Thus, our library
lets users specify the result element type of linear algebra
operations explicitly, by calling a named function that takes an
output argument explicitly, rather than an arithmetic operator.</p>
   <p>Arithmetic operators on matrices or vectors may also need to allocate
temporary storage.  Users may not want that.  When LAPACK’s developers
switched from Fortran 77 to a subset of Fortran 90, their users
rejected the option of letting LAPACK functions allocate temporary
storage on their own.  Users wanted to control memory allocation.
Also, allocating storage precludes use of nonowning input data
structures like <code class="highlight"><c- n>mdspan</c-></code>, that do not know how to allocate.</p>
   <p>Arithmetic expressions on matrices or vectors strongly suggest
expression templates, as a way to avoid allocation of temporaries and
to fuse computational kernels.  They do not <em>require</em> expression
templates.  For example, <code class="highlight"><c- n>valarray</c-></code> offers overloaded operators for
vector arithmetic, but the Standard lets implementers decide whether
to use expression templates.  However, all of the current C++ linear
algebra libraries that we mentioned above have some form of expression
templates for overloaded arithmetic operators, so users will expect
this and rely on it for good performance.  This was, indeed, one of
the major complaints about initial implementations of <code class="highlight"><c- n>valarray</c-></code>: its
lack of mandate for expression templates meant that initial
implementations were slow, and thus users did not want to rely on it.
(See Josuttis 1999, p. 547, and Vandevoorde and Josuttis 2003, p. 342,
for a summary of the history.  Fortran has an analogous issue, in
which (under certain conditions) it is implementation defined whether
the run-time environment needs to copy noncontiguous slices of an
array into contiguous temporary storage.)</p>
   <p>Expression templates work well, but have issues.  Our papers <a href="https://wg21.link/p1417r0">P1417R0</a> and
"Evolving a Standard C++ Linear Algebra Library from the BLAS" (P1674R0) give more detail on these
issues.  A particularly troublesome one is that C++ <code class="highlight"><c- k>auto</c-></code> type deduction
makes it easy for users to capture expressions
before the expression templates system
has the chance to evaluate them and write the result into the output.
For matrices and vectors with container semantics,
this makes it easy to create dangling references.
Users might not realize that they need to assign expressions to named
types before actual work and storage happen. <a href="https://eigen.tuxfamily.org/dox/TopicPitfalls.html">Eigen’s
documentation</a> describes this common problem.</p>
   <p>Our <code class="highlight"><c- n>scaled</c-></code>, <code class="highlight"><c- n>conjugated</c-></code>, <code class="highlight"><c- n>transposed</c-></code>, and <code class="highlight"><c- n>conjugate_transposed</c-></code> functions
make use of one aspect of expression templates, namely modifying the <code class="highlight"><c- n>mdspan</c-></code> array access operator.  However, we intend these
functions for use only as in-place modifications of arguments of a
function call.  Also, when modifying <code class="highlight"><c- n>mdspan</c-></code>, these functions
merely view the same data that their input <code class="highlight"><c- n>mdspan</c-></code> views.  They
introduce no more potential for dangling references than <code class="highlight"><c- n>mdspan</c-></code> itself.  The use of views like <code class="highlight"><c- n>mdspan</c-></code> is
self-documenting; it tells users that they need to take responsibility
for scope of the viewed data.</p>
   <h3 class="heading settled" data-level="10.5" id="banded-matrix-layouts"><span class="secno">10.5. </span><span class="content">Banded matrix layouts</span><a class="self-link" href="#banded-matrix-layouts"></a></h3>
   <p>This proposal omits banded matrix types.  It would be easy to add the
required layouts and specializations of algorithms later.  The packed
and unpacked symmetric and triangular layouts in this proposal cover
the major concerns that would arise in the banded case, like
nonstrided and nonunique layouts, and matrix types that forbid access
to some multi-indices in the Cartesian product of extents.</p>
   <h3 class="heading settled" data-level="10.6" id="tensors"><span class="secno">10.6. </span><span class="content">Tensors</span><a class="self-link" href="#tensors"></a></h3>
   <p>We exclude tensors from this proposal, for the following reasons.
First, tensor libraries naturally build on optimized dense linear
algebra libraries like the BLAS, so a linear algebra library is a good
first step.  Second, <code class="highlight"><c- n>mdspan</c-></code> has natural use as a
low-level representation of dense tensors, so we are already partway
there.  Third, even simple tensor operations that naturally generalize
the BLAS have infintely many more cases than linear algebra.  It’s not
clear to us which to optimize.  Fourth, even though linear algebra is
a special case of tensor algebra, users of linear algebra have
different interface expectations than users of tensor algebra.  Thus,
it makes sense to have two separate interfaces.</p>
   <h3 class="heading settled" data-level="10.7" id="explicit-support-for-asynchronous-return-of-scalar-values"><span class="secno">10.7. </span><span class="content">Explicit support for asynchronous return of scalar values</span><a class="self-link" href="#explicit-support-for-asynchronous-return-of-scalar-values"></a></h3>
   <p>After we presented revision 2 of this paper,
LEWG asked us to consider support for discrete graphics processing units (GPUs).
GPUs have two features of interest here.
First, they might have memory that is not accessible from ordinary C++ code,
but could be accessed in a standard algorithm
(or one of our proposed algorithms)
with the right implementation-specific <code class="highlight"><c- n>ExecutionPolicy</c-></code>.
(For instance, a policy could say "run this algorithm on the GPU.")
Second, they might execute those algorithms asynchronously.
That is, they might write to output arguments at some later time
after the algorithm invocation returns.
This would imply different interfaces in some cases.
For instance, a hypothetical asynchronous vector 2-norm
might write its scalar result via a pointer to GPU memory,
instead of returning the result "on the CPU."</p>
   <p>Nothing in principle prevents <code class="highlight"><c- n>mdspan</c-></code> from viewing memory
that is inaccessible from ordinary C++ code.
This is a major feature of the <code class="highlight"><c- n>Kokkos</c-><c- o>::</c-><c- n>View</c-></code> class
from the <a href="https://github.com/kokkos/kokkos">Kokkos library</a>,
and <code class="highlight"><c- n>Kokkos</c-><c- o>::</c-><c- n>View</c-></code> directly inspired <code class="highlight"><c- n>mdspan</c-></code>.
The C++ Standard does not currently define how such memory behaves,
but implementations could define its behavior and make it work with <code class="highlight"><c- n>mdspan</c-></code>.
This would, in turn, let implementations define our algorithms
to operate on such memory efficiently,
if given the right implementation-specific <code class="highlight"><c- n>ExecutionPolicy</c-></code>.</p>
   <p>Our proposal excludes algorithms that might write to their output arguments
at some time after after the algorithm returns.
First, LEWG insisted that our proposed algorithms that compute a scalar result,
like <code class="highlight"><c- n>vector_norm2</c-></code>,
return that result in the manner of <code class="highlight"><c- n>reduce</c-></code>,
rather than writing the result to an output reference or pointer.
(Previous revisions of our proposal used the latter interface pattern.)
Second, it’s not clear whether writing a scalar result to a pointer
is the right interface for asynchronous algorithms.
Follow-on proposals to <a href="https://wg21.link/p0443R14">Executors (P0443R14)</a> include asynchronous algorithms,
but none of these suggest returning results asynchronously by pointer.
Our proposal deliberately imitates the existing standard algorithms.
Right now, we have no standard asynchronous algorithms to imitate.</p>
   <h2 class="heading settled" data-level="11" id="design-justification"><span class="secno">11. </span><span class="content">Design justification</span><a class="self-link" href="#design-justification"></a></h2>
   <p>We take a step-wise approach.  We begin with core BLAS dense linear
algebra functionality.  We then deviate from that only as much as
necessary to get algorithms that behave as much as reasonable like the
existing C++ Standard Library algorithms.  Future work or
collaboration with other proposals could implement a higher-level
interface.</p>
   <p>We propose to build the initial interface on top of <code class="highlight"><c- n>mdspan</c-></code>,
and plan to extend that later with overloads for a new <code class="highlight"><c- n>mdarray</c-></code> variant of <code class="highlight"><c- n>mdspan</c-></code> with container semantics as well as any type
implementing a <code class="highlight"><c- n>get_mdspan</c-></code> customization point.
We explain the value of these choices below.</p>
   <p>Please refer to our papers "Evolving a Standard C++ Linear Algebra
Library from the BLAS" <a href="https://wg21.link/p1674r0">(P1674R0)</a> and "Historical lessons for C++ linear algebra library standardization" <a href="https://wg21.link/p1417r0">(P1417R0)</a>.  They will give details and references
for many of the points that we summarize here.</p>
   <h3 class="heading settled" data-level="11.1" id="we-do-not-require-using-the-blas-library"><span class="secno">11.1. </span><span class="content">We do not require using the BLAS library</span><a class="self-link" href="#we-do-not-require-using-the-blas-library"></a></h3>
   <p>Our proposal is based on the BLAS interface, and it would be natural
for implementers to use an existing C or Fortran BLAS library.
However, we do not require an underlying BLAS C interface.
Vendors should have the freedom to decide whether they want to rely on an
existing BLAS library.
They may also want to write a "pure" C++
implementation that does not depend on an external library.  They
will, in any case, need a "generic" C++ implementation for matrix and
vector element types other than the four that the BLAS supports.</p>
   <h3 class="heading settled" data-level="11.2" id="why-use-mdspan"><span class="secno">11.2. </span><span class="content">Why use <code class="highlight"><c- n>mdspan</c-></code>?</span><a class="self-link" href="#why-use-mdspan"></a></h3>
   <h4 class="heading settled" data-level="11.2.1" id="view-of-a-multidimensional-array"><span class="secno">11.2.1. </span><span class="content">View of a multidimensional array</span><a class="self-link" href="#view-of-a-multidimensional-array"></a></h4>
   <p>The BLAS operates on what C++ programmers might call views of multidimensional arrays.
Users of the BLAS can store their data in whatever data structures they like,
and handle their allocation and lifetime as they see fit,
as long as the data have a BLAS-compatible memory layout.</p>
   <p>The corresponding C++ data structure is <code class="highlight"><c- n>mdspan</c-></code>.
This class encapsulates the large number of pointer and integer arguments
that BLAS functions take, that represent views of matrices and vectors.
Using <code class="highlight"><c- n>mdspan</c-></code> in the C++ interface reduce the number of arguments
and avoids common errors, like mixing up the order of arguments.
It supports all the array memory layouts that the BLAS supports,
including row major and column major.
It also expresses the same data ownership model that the BLAS expresses.
Users may manage allocation and deallocation however they wish.
In addition, <code class="highlight"><c- n>mdspan</c-></code> lets our algorithms exploit any dimensions known at compile time.</p>
   <h4 class="heading settled" data-level="11.2.2" id="ease-of-use"><span class="secno">11.2.2. </span><span class="content">Ease of use</span><a class="self-link" href="#ease-of-use"></a></h4>
   <p>The <code class="highlight"><c- n>mdspan</c-></code> class' layout and accessor policies
let us simplify our interfaces,
by encapsulating transpose, conjugate, and scalar arguments.
Features of <code class="highlight"><c- n>mdspan</c-></code> make implementing BLAS-like algorithms
much less error prone and easier to read.
These include its encapsulation of matrix indexing
and its built-in "slicing" capabilities via <code class="highlight"><c- n>submdspan</c-></code>.</p>
   <h4 class="heading settled" data-level="11.2.3" id="blas-and-mdspan-are-low-level"><span class="secno">11.2.3. </span><span class="content">BLAS and <code class="highlight"><c- n>mdspan</c-></code> are low level</span><a class="self-link" href="#blas-and-mdspan-are-low-level"></a></h4>
   <p>The BLAS is low level; it imposes no mathematical meaning on multidimensional arrays.
This gives users the freedom to develop mathematical libraries with the semantics they want.
Similarly, <code class="highlight"><c- n>mdspan</c-></code> is just a view of a multidimensional array;
it has no mathematical meaning on its own.</p>
   <p>We mention this because "matrix," "vector," and "tensor"
are mathematical ideas that mean more than just arrays of numbers.
This is more than just a theoretical concern.
Some BLAS functions operate on "triangular," "symmetric," or "Hermitian" matrices,
but they do not assert that a matrix has any of these mathematical properties.
Rather, they only read only one side of the matrix (the lower or upper triangle),
and compute as if the rest of the matrix satisfies the mathematical property.
A key feature of the BLAS and libraries that build on it, like LAPACK,
is that they can operate on the matrix’s data in place.
These operations change both the matrix’s mathematical properties and its representation in memory.
For example, one might have an N x N array representing a matrix that is symmetric in theory,
but computed and stored in a way that might not result in exactly symmetric data.
In order to solve linear systems with this matrix,
one might give the array to LAPACK’s <code class="highlight"><c- n>xSYTRF</c-></code> to compute an LDL^T factorization,
asking <code class="highlight"><c- n>xSYTRF</c-></code> only to access the array’s lower triangle.
If <code class="highlight"><c- n>xSYTRF</c-></code> finishes successfully,
it has overwritten the lower triangle of its input
with a representation of both the lower triangular factor L
and the block diagonal matrix D,
as computed assuming that the matrix is the sum of the lower triangle
and the transpose of the lower triangle.
The resulting N x N array no longer represents a symmetric matrix.
Rather, it contains part of the representation of a LDL^T factorization of the matrix.
The upper triangle still contains the original input matrix’s data.
One may then solve linear systems by giving <code class="highlight"><c- n>xSYTRS</c-></code> the lower triangle,
along with other output of <code class="highlight"><c- n>xSYTRF</c-></code>.</p>
   <p>The point of this example is that a "symmetric matrix class"
is the wrong way to model this situation.
There’s an N x N array, whose mathematical interpretation changes
with each in-place operation performed on it.
The low-level <code class="highlight"><c- n>mdspan</c-></code> data structure carries no mathematical properties in itself,
so it models this situation better.</p>
   <h4 class="heading settled" data-level="11.2.4" id="hook-for-future-expansion"><span class="secno">11.2.4. </span><span class="content">Hook for future expansion</span><a class="self-link" href="#hook-for-future-expansion"></a></h4>
   <p>The <code class="highlight"><c- n>mdspan</c-></code> class treats its layout as an extension point.
This lets our interface support layouts beyond what the BLAS Standard permits.
The accessor extension point offers us a hook for future expansion
to support heterogeneous memory spaces.
(This is a key feature of <code class="highlight"><c- n>Kokkos</c-><c- o>::</c-><c- n>View</c-></code>,
the data structure that inspired <code class="highlight"><c- n>mdspan</c-></code>.)
In addition, using <code class="highlight"><c- n>mdspan</c-></code> will make it easier for us to add
an efficient "batched" interface in future proposals.</p>
   <h4 class="heading settled" data-level="11.2.5" id="generic-enough-to-replace-a-multidimensional-array-concept"><span class="secno">11.2.5. </span><span class="content">Generic enough to replace a "multidimensional array concept"</span><a class="self-link" href="#generic-enough-to-replace-a-multidimensional-array-concept"></a></h4>
   <p>LEWGI requested in the 2019 Cologne meeting that we explore using a
concept instead of <code class="highlight"><c- n>mdspan</c-></code> to define the arguments for the
linear algebra functions.
This would mean, instead of having our functions take <code class="highlight"><c- n>mdspan</c-></code> parameters,
they would be generic on one or more suitably constrained multidimensional array types.
The constraints would form a "multidimensional array concept."</p>
   <p>We investigated this option, and rejected it, for the following reasons.</p>
   <ol>
    <li data-md>
     <p>Our proposal uses enough features of <code class="highlight"><c- n>mdspan</c-></code> that any concept generally applicable to all functions we propose
would largely replicate the definition of <code class="highlight"><c- n>mdspan</c-></code>.</p>
    <li data-md>
     <p>This proposal could support most multidimensional array types,
if the array types just made themselves convertible to <code class="highlight"><c- n>mdspan</c-></code>.</p>
    <li data-md>
     <p>We could always generalize our algorithms later.</p>
    <li data-md>
     <p>Any multidimensional array concept would need revision
in the light of <a href="https://wg21.link/p2128r6">P2128R6</a>.</p>
   </ol>
   <p>This proposal refers to almost all of <code class="highlight"><c- n>mdspan</c-></code>'s features,
including <code class="highlight"><c- n>extents</c-></code>, <code class="highlight"><c- n>layout</c-></code>, and <code class="highlight"><c- n>accessor_policy</c-></code>.
We expect implementations to use all of them for optimizations,
for example to extract the scaling factor from the return value of <code class="highlight"><c- n>scaled</c-></code> in order to call an optimized BLAS library directly.</p>
   <p>Suppose that a general customization point <code class="highlight"><c- n>get_mdspan</c-></code> existed,
that takes a reference to a multidimensional array type
and returns an <code class="highlight"><c- n>mdspan</c-></code> that views the array.
Then, our proposal could support most multidimensional array types.
"Most" includes all such types that refer to a subset of a contiguous span of memory.</p>
   <p>Requiring that a multidimensional array refer to a subset of a contiguous span of memory
would exclude multidimensional array types that have a noncontiguous backing store,
such as a <code class="highlight"><c- n>map</c-></code>.
If we later wanted to support such types,
we could always generalize our algorithms later.</p>
   <p>Finally, any multidimensional array concept would need revision
in the light of <a href="https://wg21.link/p2128r6">P2128R6</a>,
which has been approved at Plenary.
P2128 lets <code class="highlight"><c- k>operator</c-><c- p>[]</c-></code> take multiple parameters.
Its authors intend to let <code class="highlight"><c- n>mdspan</c-></code> use <code class="highlight"><c- k>operator</c-><c- p>[]</c-></code> instead of <code class="highlight"><c- k>operator</c-><c- p>()</c-></code>.
P0009 has adopted this change.</p>
   <p>After further discussion at the 2019 Belfast meeting,
LEWGI accepted our position that having our algorithms take <code class="highlight"><c- n>mdspan</c-></code> instead of template parameters constrained by a multidimensional array concept
would be fine for now.</p>
   <h3 class="heading settled" data-level="11.3" id="function-argument-aliasing-and-zero-scalar-multipliers"><span class="secno">11.3. </span><span class="content">Function argument aliasing and zero scalar multipliers</span><a class="self-link" href="#function-argument-aliasing-and-zero-scalar-multipliers"></a></h3>
   <p>Summary:</p>
   <ol>
    <li data-md>
     <p>The BLAS Standard forbids aliasing any input (read-only) argument
with any output (write-only or read-and-write) argument.</p>
    <li data-md>
     <p>The BLAS uses <code class="highlight"><c- n>INTENT</c-><c- p>(</c-><c- n>INOUT</c-><c- p>)</c-></code> (read-and-write) arguments to express
"updates" to a vector or matrix.  By contrast, C++ Standard
algorithms like <code class="highlight"><c- n>transform</c-></code> take input and output iterator ranges
as different parameters, but may let input and output ranges be the
same.</p>
    <li data-md>
     <p>The BLAS uses the values of scalar multiplier arguments ("alpha" or
"beta") of vectors or matrices at run time, to decide whether to
treat the vectors or matrices as write only.  This matters both for
performance and semantically, assuming IEEE floating-point
arithmetic.</p>
    <li data-md>
     <p>We decide separately, based on the category of BLAS function, how
to translate <code class="highlight"><c- n>INTENT</c-><c- p>(</c-><c- n>INOUT</c-><c- p>)</c-></code> arguments into a C++ idiom:</p>
   </ol>
   <p>a. For triangular solve and triangular multiply, in-place behavior
      is essential for computing matrix factorizations in place,
      without requiring extra storage proportional to the input
      matrix’s dimensions.  However, in-place functions cannot be
      parallelized for arbitrary execution policies.  Thus, we have
      both not-in-place and in-place overloads, and only the
      not-in-place overloads take an optional <code class="highlight"><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-></code>.</p>
   <p>b. Else, if the BLAS function unconditionally updates (like <code class="highlight"><c- n>xGER</c-></code>), we retain read-and-write behavior for that argument.</p>
   <p>c. Else, if the BLAS function uses a scalar <code class="highlight"><c- n>beta</c-></code> argument to
      decide whether to read the output argument as well as write to
      it (like <code class="highlight"><c- n>xGEMM</c-></code>), we provide two versions: a write-only version
      (as if <code class="highlight"><c- n>beta</c-></code> is zero), and a read-and-write version (as if <code class="highlight"><c- n>beta</c-></code> is nonzero).</p>
   <p>For a detailed analysis, see "Evolving a Standard C++ Linear Algebra
Library from the BLAS" (P1674R0).</p>
   <h3 class="heading settled" data-level="11.4" id="support-for-different-matrix-layouts"><span class="secno">11.4. </span><span class="content">Support for different matrix layouts</span><a class="self-link" href="#support-for-different-matrix-layouts"></a></h3>
   <p>Summary:</p>
   <ol>
    <li data-md>
     <p>The dense BLAS supports several different dense matrix "types."
Type is a mixture of "storage format" (e.g., packed, banded) and
"mathematical property" (e.g., symmetric, Hermitian, triangular).</p>
    <li data-md>
     <p>Some "types" can be expressed as custom <code class="highlight"><c- n>mdspan</c-></code> layouts.
Other types actually represent algorithmic constraints: for
instance, what entries of the matrix the algorithm is allowed to
access.</p>
    <li data-md>
     <p>Thus, a C++ BLAS wrapper cannot overload on matrix "type" simply by
overloading on <code class="highlight"><c- n>mdspan</c-></code> specialization.  The wrapper must use
different function names, tags, or some other way to decide what
the matrix type is.</p>
   </ol>
   <p>For more details, including a list and description of the matrix
"types" that the dense BLAS supports, see our paper "Evolving a
Standard C++ Linear Algebra Library from the BLAS" (P1674R0).</p>
   <p>A C++ linear algebra library has a few possibilities for
distinguishing the matrix "type":</p>
   <ol>
    <li data-md>
     <p>It could imitate the BLAS, by introducing different function names,
if the layouts and accessors do not sufficiently describe the
arguments.</p>
    <li data-md>
     <p>It could introduce a hierarchy of higher-level classes for
representing linear algebra objects, use <code class="highlight"><c- n>mdspan</c-></code> (or
something like it) underneath, and write algorithms to those
higher-level classes.</p>
    <li data-md>
     <p>It could use the layout and accessor types in <code class="highlight"><c- n>mdspan</c-></code> simply
as tags to indicate the matrix "type."  Algorithms could specialize
on those tags.</p>
   </ol>
   <p>We have chosen Approach 1.  Our view is that a BLAS-like interface
should be as low-level as possible.  Approach 2 is more like a "Matlab
in C++"; a library that implements this could build on our proposal’s
lower-level library.  Approach 3 <em>sounds</em> attractive.  However, most
BLAS matrix "types" do not have a natural representation as layouts.
Trying to hack them in would pollute <code class="highlight"><c- n>mdspan</c-></code> -- a simple class
meant to be easy for the compiler to optimize -- with extra baggage
for representing what amounts to sparse matrices.  We think that BLAS
matrix "type" is better represented with a higher-level library that
builds on our proposal.</p>
   <h3 class="heading settled" data-level="11.5" id="over--and-underflow-wording-for-vector-2-norm"><span class="secno">11.5. </span><span class="content">Over- and underflow wording for vector 2-norm</span><a class="self-link" href="#over--and-underflow-wording-for-vector-2-norm"></a></h3>
   <p>SG6 recommended to us at Belfast 2019 to change the special overflow /
underflow wording for <code class="highlight"><c- n>vector_norm2</c-></code> to imitate the BLAS Standard more
closely.  The BLAS Standard does say something about overflow and
underflow for vector 2-norms.  We reviewed this wording and conclude
that it is either a nonbinding quality of implementation (QoI)
recommendation, or too vaguely stated to translate directly into C++
Standard wording.
Thus, we removed our special overflow / underflow wording.
However, the BLAS Standard clearly expresses the intent
that implementations document their underflow and overflow guarantees
for certain functions, like vector 2-norms.
The C++ Standard requires documentation of "implementation-defined behavior."
Therefore, we added language to our proposal that makes
"any guarantees regarding overflow and underflow" of those certain functions
"implementation-defined."</p>
   <p>Previous versions of this paper asked implementations to compute
vector 2-norms "without undue overflow or underflow at intermediate
stages of the computation."  "Undue" imitates existing C++ Standard
wording for <code class="highlight"><c- n>hypot</c-></code>.  This wording hints at the stricter requirements
in F.9 (normative, but optional) of the C Standard for math library
functions like <code class="highlight"><c- n>hypot</c-></code>, without mandating those requirements.  In
particular, paragraph 9 of F.9 says:</p>
   <blockquote>
    <p>Whether or when library functions raise an undeserved "underflow"
floating-point exception is unspecified.  Otherwise, as implied by
F.7.6, the <strong>&lt;math.h></strong> functions do not raise spurious
floating-point exceptions (detectable by the user) [including the
"overflow" exception discussed in paragraph 6], other than the
"inexact" floating-point exception.</p>
   </blockquote>
   <p>However, these requirements are for math library functions like <code class="highlight"><c- n>hypot</c-></code>, not for general algorithms that return floating-point values.
SG6 did not raise a concern that we should treat <code class="highlight"><c- n>vector_norm2</c-></code> like a
math library function; their concern was that we imitate the BLAS
Standard’s wording.</p>
   <p>The BLAS Standard says of several operations, including vector 2-norm:
"Here are the exceptional routines where we ask for particularly
careful implementations to avoid unnecessary over/underflows, that
could make the output unnecessarily inaccurate or unreliable" (p. 35).</p>
   <p>The BLAS Standard does not define phrases like "unnecessary
over/underflows."  The likely intent is to avoid naïve implementations
that simply add up the squares of the vector elements.  These would
overflow even if the norm in exact arithmetic is significantly less
than the overflow threshold.  The POSIX Standard (IEEE Std
1003.1-2017) analogously says that <code class="highlight"><c- n>hypot</c-></code> must "take precautions
against overflow during intermediate steps of the computation."</p>
   <p>The phrase "precautions against overflow" is too vague for us to
translate into a requirement.  The authors likely meant to exclude
naïve implementations, but not require implementations to know whether
a result computed in exact arithmetic would overflow or underflow.
The latter is a special case of computing floating-point sums exactly,
which is costly for vectors of arbitrary length.  While it would be a
useful feature, it is difficult enough that we do not want to require
it, especially since the BLAS Standard itself does not.
The implementation of vector 2-norms in the Reference BLAS included with LAPACK 3.10.0
partitions the running sum of squares into three different accumulators:
one for big values (that might cause the sum to overflow without rescaling),
one for small values (that might cause the sum to underflow without rescaling),
and one for the remaining "medium" values.
(See Anderson 2017.)
Earlier implementations merely rescaled by the current maximum absolute value
of all the vector entries seen thus far.
(See Blue 1978.)
Implementations could also just compute the sum of squares in a straightforward loop,
then check floating-point status flags for underflow or overflow,
and recompute if needed.</p>
   <p>For all of the functions listed on p. 35 of the BLAS Standard as
needing "particularly careful implementations," <em>except</em> vector norm,
the BLAS Standard has an "Advice to implementors" section with extra
accuracy requirements.  The BLAS Standard does have an "Advice to
implementors" section for matrix norms (see Section 2.8.7, p. 69),
which have similar over- and underflow concerns as vector norms.
However, the Standard merely states that "[h]igh-quality
implementations of these routines should be accurate" and should
document their accuracy, and gives examples of "accurate
implementations" in LAPACK.</p>
   <p>The BLAS Standard never defines what "Advice to implementors" means.
However, the BLAS Standard shares coauthors and audience with the
Message Passing Interface (MPI) Standard, which defines "Advice to
implementors" as "primarily commentary to implementors" and
permissible to skip (see e.g., MPI 3.0, Section 2.1, p. 9).  We thus
interpret "Advice to implementors" in the BLAS Standard as a
nonbinding quality of implementation (QoI) recommendation.</p>
   <h3 class="heading settled" data-level="11.6" id="constraining-matrix-and-vector-element-types-and-scalars"><span class="secno">11.6. </span><span class="content">Constraining matrix and vector element types and scalars</span><a class="self-link" href="#constraining-matrix-and-vector-element-types-and-scalars"></a></h3>
   <h4 class="heading settled" data-level="11.6.1" id="introduction"><span class="secno">11.6.1. </span><span class="content">Introduction</span><a class="self-link" href="#introduction"></a></h4>
   <p>The BLAS only accepts four different types of scalars and matrix and vector elements.
In C++ terms, these correspond to <code class="highlight"><c- b>float</c-></code>, <code class="highlight"><c- b>double</c-></code>, <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- b>float</c-><c- o>></c-></code>, and <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- b>double</c-><c- o>></c-></code>.
The algorithms we propose generalize the BLAS
by accepting any matrix, vector, or scalar element types that make sense for each algorithm.
Those may be built-in types, like floating-point numbers or integers,
or they may be custom types.
Those custom types might not behave like conventional real or complex numbers.
For example, quaternions have noncommutative multiplication (<code class="highlight"><c- n>a</c-> <c- o>*</c-> <c- n>b</c-></code> might not equal <code class="highlight"><c- n>b</c-> <c- o>*</c-> <c- n>a</c-></code>),
polynomials in one variable over a field lack division,
and some types might not even have subtraction defined.
Nevertheless, many BLAS operations would make sense for all of these types.</p>
   <p>"Constraining matrix and vector element types and scalars"
means defining how these types must behave
in order for our algorithms to make sense.
This includes both syntactic and semantic constraints.
We have three goals:</p>
   <ol>
    <li data-md>
     <p>to help implementers implement our algorithms correctly;</p>
    <li data-md>
     <p>to give implementers the freedom to make quality of implementation (QoI) enhancements,
for both performance and accuracy; and</p>
    <li data-md>
     <p>to help users understand what types they may use with our algorithms.</p>
   </ol>
   <p>The whole point of the BLAS was to identify key operations
for vendors to optimize.
Thus, performance is a major concern.
"Accuracy" here refers to either to rounding error or to approximation error
(for matrix or vector element types where either makes sense).</p>
   <h4 class="heading settled" data-level="11.6.2" id="value-type-constraints-do-not-suffice-to-describe-algorithm-behavior"><span class="secno">11.6.2. </span><span class="content">Value type constraints do not suffice to describe algorithm behavior</span><a class="self-link" href="#value-type-constraints-do-not-suffice-to-describe-algorithm-behavior"></a></h4>
   <p>LEWG’s 2020 review of P1673R2 asked us to investigate conceptification of its algorithms.
"Conceptification" here refers to an effort like that of P1813R0
("A Concept Design for the Numeric Algorithms"),
to come up with concepts that could be used to constrain the template parameters
of numeric algorithms like <code class="highlight"><c- n>reduce</c-></code> or <code class="highlight"><c- n>transform</c-></code>.
(We are not referring to LEWGI’s request for us to consider
generalizing our algorithm’s parameters from <code class="highlight"><c- n>mdspan</c-></code> to a hypothetical multidimensional array concept.
We discuss that above, in the "Why use <code class="highlight"><c- n>mdspan</c-></code>?" section.)
The numeric algorithms are relevant to P1673 because many of the algorithms proposed in P1673
look like generalizations of <code class="highlight"><c- n>reduce</c-></code> or <code class="highlight"><c- n>transform</c-></code>.
We intend for our algorithms to be generic on their matrix and vector element types,
so these questions matter a lot to us.</p>
   <p>We agree that it is useful to set constraints
that make it possible to reason about correctness of algorithms.
However, we do not think constraints on value types suffice for this purpose.
First, requirements like associativity are too strict to be useful for practical types.
Second, what we really want to do is describe the behavior of algorithms,
regardless of value types' semantics.
"The algorithm may reorder sums" means something different
than "addition on the terms in the sum is associative."</p>
   <h4 class="heading settled" data-level="11.6.3" id="associativity-is-too-strict"><span class="secno">11.6.3. </span><span class="content">Associativity is too strict</span><a class="self-link" href="#associativity-is-too-strict"></a></h4>
   <p>P1813R0 requires associative addition for many algorithms, such as <code class="highlight"><c- n>reduce</c-></code>.
However, many practical arithmetic systems that users might like to use
with algorithms like <code class="highlight"><c- n>reduce</c-></code> have non-associative addition.  These include</p>
   <ul>
    <li data-md>
     <p>systems with rounding;</p>
    <li data-md>
     <p>systems with an "infinity": e.g., if 10 is Inf, 3 + 8 - 7 could be either Inf or 4; and</p>
    <li data-md>
     <p>saturating arithmetic: e.g., if 10 saturates, 3 + 8 - 7 could be either 3 or 4.</p>
   </ul>
   <p>Note that the latter two arithmetic systems have nothing to do with rounding error.
With saturating integer arithmetic, parenthesizing a sum in different ways might give results
that differ by as much as the saturation threshold.
It’s true that many non-associative arithmetic systems behave
"associatively enough" that users don’t fear parallelizing sums.
However, a concept with an exact property (like "commutative semigroup")
isn’t the right match for "close enough,"
just like <code class="highlight"><c- k>operator</c-><c- o>==</c-></code> isn’t the right match for describing "nearly the same."
For some number systems, a rounding error bound might be more appropriate,
or guarantees on when underflow or overflow may occur (as in POSIX’s <code class="highlight"><c- n>hypot</c-></code>).</p>
   <p>The problem is a mismatch between the requirement we want to express —<wbr>that "the algorithm may reparenthesize addition" —<wbr>and the constraint that "addition is associative."
The former describes the algorithm’s behavior,
while the latter describes the types used with that algorithm.
Given the huge variety of possible arithmetic systems,
an approach like the Standard’s use of <em>GENERALIZED_SUM</em> to describe <code class="highlight"><c- n>reduce</c-></code> and its kin seems more helpful.
If the Standard describes an algorithm in terms of <em>GENERALIZED_SUM</em>,
then that tells the caller what the algorithm might do.
The caller then takes responsibility for interpreting the algorithm’s results.</p>
   <p>We think this is important both for adding new algorithms (like those in this proposal)
and for defining behavior of an algorithm with respect to different <code class="highlight"><c- n>ExecutionPolicy</c-></code> arguments.
(For instance, <code class="highlight"><c- n>execution</c-><c- o>::</c-><c- n>par_unseq</c-></code> could imply that the algorithm might change the order of terms in a sum,
while <code class="highlight"><c- n>execution</c-><c- o>::</c-><c- n>par</c-></code> need not.
Compare to <code class="highlight"><c- n>MPI_Op_create</c-></code>'s <code class="highlight"><c- n>commute</c-></code> parameter,
that affects the behavior of algorithms like <code class="highlight"><c- n>MPI_Reduce</c-></code> when used with the resulting user-defined reduction operator.)</p>
   <h4 class="heading settled" data-level="11.6.4" id="generalizing-associativity-helps-little"><span class="secno">11.6.4. </span><span class="content">Generalizing associativity helps little</span><a class="self-link" href="#generalizing-associativity-helps-little"></a></h4>
   <p>Suppose we accept that associativity and related properties are not useful
for describing our proposed algorithms.
Could there be a generalization of associativity that <em>would</em> be useful?
P1813R0’s most general concept is a <code class="highlight"><c- n>magma</c-></code>.
Mathematically, a <em>magma</em> is a set M with a binary operation ×,
such that if a and b are in M, then a × b is in M.
The operation need not be associative or commutative.
While this seems almost too general to be useful,
there are two reasons why even a magma is too specific for our proposal.</p>
   <ol>
    <li data-md>
     <p>A magma only assumes one set, that is, one type.
This does not accurately describe what the algorithms do,
and it excludes useful features like mixed precision and types that use expression templates.</p>
    <li data-md>
     <p>A magma is too specific, because algorithms are useful even if the binary operation is not closed.</p>
   </ol>
   <p>First, even for simple linear algebra operations that "only" use plus and times,
there is no one "set M" over which plus and times operate.
There are actually three operations: plus, times, and assignment.
Each operation may have completely heterogeneous input(s) and output.
The sets (types) that may occur vary from algorithm to algorithm,
depending on the input type(s),
and the algebraic expression(s) that the algorithm is allowed to use.
We might need several different concepts to cover all the expressions that algorithms use,
and the concepts would end up being less useful to users than the expressions themselves.</p>
   <p>For instance, consider the Level 1 BLAS "AXPY" function.
This computes <code class="highlight"><c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-> <c- n>alpha</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>+</c-> <c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code> elementwise.
What type does the expression <code class="highlight"><c- n>alpha</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>+</c-> <c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code> have?
It doesn’t need to have the same type as <code class="highlight"><c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code>;
it just needs to be assignable to <code class="highlight"><c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code>.
The types of <code class="highlight"><c- n>alpha</c-></code>, <code class="highlight"><c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code>, and <code class="highlight"><c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code> could all differ.
As a simple example, <code class="highlight"><c- n>alpha</c-></code> might be <code class="highlight"><c- b>int</c-></code>, <code class="highlight"><c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code> might be <code class="highlight"><c- b>float</c-></code>, and <code class="highlight"><c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code> might be <code class="highlight"><c- b>double</c-></code>.
The types of <code class="highlight"><c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code> and <code class="highlight"><c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code> might be more complicated;
e.g., <code class="highlight"><c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code> might be a polynomial with <code class="highlight"><c- b>double</c-></code> coefficients,
and <code class="highlight"><c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code> a polynomial with <code class="highlight"><c- b>float</c-></code> coefficients.
If those polynomials use expression templates,
then slightly different sum expressions involving <code class="highlight"><c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code> and/or <code class="highlight"><c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code> (e.g., <code class="highlight"><c- n>alpha</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>+</c-> <c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code>, <code class="highlight"><c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>+</c-> <c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code>, or <code class="highlight"><c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>+</c-> <c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code>)
might all have different types,
all of which differ from value type of <code class="highlight"><c- n>x</c-></code> or <code class="highlight"><c- n>y</c-></code>.
All of these types must be assignable and convertible to the output value type.</p>
   <p>We could try to describe this with a concept that expresses a sum type.
The sum type would include all the types that might show up in the expression.
However, we do not think this would improve clarity over just the expression itself.
Furthermore, different algorithms may need different expressions,
so we would need multiple concepts, one for each expression.
Why not just use the expressions to describe what the algorithms can do?</p>
   <p>Second, the magma concept is not helpful even if we only had one set M,
because our algorithms would still be useful even if binary operations were not closed over that set.
For example, consider a hypothetical user-defined rational number type,
where plus and times throw if representing the result of the operation
would take more than a given fixed amount of memory.
Programmers might handle this exception by falling back to different algorithms.
Neither plus or times on this type would satisfy the magma requirement,
but the algorithms would still be useful for such a type.
One could consider the magma requirement satisfied in a purely syntactic sense,
because of the return type of plus and times.
However, saying that would not accurately express the type’s behavior.</p>
   <p>This point returns us to the concerns we expressed earlier about assuming associativity.
"Approximately associative" or "usually associative" are not useful concepts without further refinement.
The way to refine these concepts usefully is to describe the behavior of a type fully,
e.g., the way that IEEE 754 describes the behavior of floating-point numbers.
However, algorithms rarely depend on all the properties in a specification like IEEE 754.
The problem, again, is that we need to describe
what algorithms do -- e.g., that they can rearrange terms in a sum -- not how the types
that go into the algorithms behave.</p>
   <p>In summary:</p>
   <ul>
    <li data-md>
     <p>Many useful types have nonassociative or even non-closed arithmetic.</p>
    <li data-md>
     <p>Lack of (e.g.,) associativity is not just a rounding error issue.</p>
    <li data-md>
     <p>It can be useful to let algorithms do things like reparenthesize sums or products,
even for types that are not associative.</p>
    <li data-md>
     <p>Permission for an algorithm to reparenthesize sums
is not the same as a concept constraining the terms in the sum.</p>
    <li data-md>
     <p>We can and do use existing Standard language, like <em>GENERALIZED_SUM</em>,
for expressing permissions that algorithms have.</p>
   </ul>
   <p>In the sections that follow, we will describe a different way
to constrain the matrix and vector element types and scalars in our algorithms.
We will start by categorizing the different quality of implementation (QoI) enhancements
that implementers might like to make.
These enhancements call for changing algorithms in different ways.
We will distinguish textbook from non-textbook ways of changing algorithms,
explain that we only permit non-textbook changes for floating-point types,
then develop constraints on types that permit textbook changes.</p>
   <h4 class="heading settled" data-level="11.6.5" id="categories-of-qoi-enhancements"><span class="secno">11.6.5. </span><span class="content">Categories of QoI enhancements</span><a class="self-link" href="#categories-of-qoi-enhancements"></a></h4>
   <p>An important goal of constraining our algorithms is
to give implementers the freedom to make QoI enhancements.
We categorize QoI enhancements in three ways:</p>
   <ol>
    <li data-md>
     <p>those that depend entirely on the computer architecture;</p>
    <li data-md>
     <p>those that might have architecture-dependent parameters,
but could otherwise be written in an architecture-independent way; and</p>
    <li data-md>
     <p>those that diverge from a textbook description of the algorithm,
and depend on element types having properties more specific
than what that description requires.</p>
   </ol>
   <p>An example of Category (1) would be special hardware instructions
that perform matrix-matrix multiplications on small, fixed-size blocks.
The hardware might only support a few types,
such as integers, fixed-point reals, or floating-point types.
Implementations might use these instructions for the entire algorithm,
if the problem sizes and element types match the instruction’s requirements.
They might also use these instructions to solve subproblems.
In either case, these instructions might reorder sums
or create temporary values.</p>
   <p>Examples of Category (2) include blocking
to increase cache or translation lookaside buffer (TLE) reuse,
or using SIMD instructions (given the Parallelism TS' inclusion of SIMD).
Many of these optimizations relate to memory locality or parallelism.
For an overview, see (Goto 2008) or Section 2.6 of (Demmel 1997).
All such optimizations reorder sums and create temporary values.</p>
   <p>Examples of Category (3) include Strassen’s algorithm for matrix multiplication.
The textbook formulation of matrix multiplication only uses additions and multiplies,
but Strassen’s algorithm also performs subtractions.
A common feature of Category (3) enhancements
is that their implementation diverges
from a "textbook description of the algorithm"
in ways beyond just reordering sums.
As a "textbook," we recommend either (Strang 2016),
or the concise mathematical description of operations in the BLAS Standard.
In the next section, we will list properties of textbook descriptions,
and explain some ways in which QoI enhancements might fail to adhere to those properties.</p>
   <h4 class="heading settled" data-level="11.6.6" id="properties-of-textbook-algorithm-descriptions"><span class="secno">11.6.6. </span><span class="content">Properties of textbook algorithm descriptions</span><a class="self-link" href="#properties-of-textbook-algorithm-descriptions"></a></h4>
   <p>"Textbook descriptions" of the algorithms we propose
tend to have the following properties.
For each property, we give an example of a "non-textbook" algorithm,
and how it assumes something extra about the matrix’s element type.</p>
   <p>a. They compute floating-point sums straightforwardly
   (possibly reordered, or with temporary intermediate values),
   rather than using any of several algorithms that improve accuracy
   (e.g., compensated summation)
   or even make the result independent of evaluation order (see Demmel 2013).
   All such non-straightforward algorithms
   depend on properties of floating-point arithmetic.
   We will define below what "possibly reordered,
   or with temporary intermediate values" means.</p>
   <p>b. They use only those arithmetic operations
   on the matrix and vector element types
   that the textbook description of the algorithm requires,
   even if using other kinds of arithmetic operations
   would improve performance
   or give an asymptotically faster algorithm.</p>
   <p>c. They use exact algorithms (not considering rounding error),
   rather than approximations
   (that would not be exact even if computing with real numbers).</p>
   <p>d. They do not use parallel algorithms
   that would give an asymptotically faster parallelization
   in the theoretical limit of infinitely many available parallel processing units,
   at the cost of likely unacceptable rounding error in floating-point arithmetic.</p>
   <p>As an example of (b), the textbook matrix multiplication algorithm
only adds or multiplies the matrices' elements.
In contrast, Strassen’s algorithm for matrix-matrix multiply
subtracts as well as adds and multiplies the matrices' elements.
Use of subtraction assumes that arbitrary elements have an additive inverse,
but the textbook matrix multiplication algorithm makes sense
even for element types that lack additive inverses for all elements.
Also, use of subtractions changes floating-point rounding behavior
in a way that was only fully understood recently (see Demmel 2007).</p>
   <p>As an example of (c), the textbook substitution algorithm
for solving triangular linear systems is exact.
In contrast, one can approximate triangular solve with a stationary iteration.
(See, e.g., Section 5 of (Chow 2015).
That paper concerns the sparse matrix case;
we cite it merely as an example of an approximate algorithm,
not as a recommendation for dense triangular solve.)
Approximation only makes sense for element types
that have enough precision for the approximation to be accurate.
If the approximation checks convergence,
than the algorithm also requires less-than comparison
of absolute values of differences.</p>
   <p>Multiplication by the reciprocal of a number,
rather than division by that number,
could fit into (b) or (c).
As an example of (c), implementations for hardware
where floating-point division is slow compared with multiplication
could use an approximate reciprocal multiplication to implement division.</p>
   <p>As an example of (d), the textbook substitution algorithm
for solving triangular linear systems has data dependencies
that limit its theoretical parallelism.
In contrast, one can solve a triangular linear system
by building all powers of the matrix in parallel,
then solving the linear system as with a Krylov subspace method.
This approach is exact for real numbers,
but commits too much rounding error to be useful in practice
for all but the smallest linear systems.
In fact, the algorithm requires that the matrix’s element type
have precision exponential in the matrix’s dimension.</p>
   <p>Many of these non-textbook algorithms rely on properties of floating-point arithmetic.
Strassen’s algorithm makes sense for unsigned integer types,
but it could lead to unwarranted and unexpected overflow for signed integer types.
Thus, we think it best to limit implementers to textbook algorithms,
unless all matrix and vector element types are floating-point types.
We always forbid non-textbook algorithms of type (d).
If all matrix and vector element types are floating-point types,
we permit non-textbook algorithms of Types (a), (b), and (c),
under two conditions:</p>
   <ol>
    <li data-md>
     <p>they satisfy the complexity requirements; and</p>
    <li data-md>
     <p>they result in a <em>logarithmically stable</em> algorithm,
in the sense of (Demmel 2007).</p>
   </ol>
   <p>We believe that Condition (2) is a reasonable interpretation of Section 2.7 of the BLAS Standard.
This says that "no particular computational order is mandated by the function specifications.
In other words, any algorithm that produces results 'close enough'
to the usual algorithms presented in a standard book on matrix computations
is acceptable."
Examples of what the BLAS Standard considers "acceptable"
include Strassen’s algorithm, and implementing matrix multiplication as <code class="highlight"><c- n>C</c-> <c- o>=</c-> <c- p>(</c-><c- n>alpha</c-> <c- o>*</c-> <c- n>A</c-><c- p>)</c-> <c- o>*</c-> <c- n>B</c-> <c- o>+</c-> <c- p>(</c-><c- n>beta</c-> <c- o>*</c-> <c- n>C</c-><c- p>)</c-></code>, <code class="highlight"><c- n>C</c-> <c- o>=</c-> <c- n>alpha</c-> <c- o>*</c-> <c- p>(</c-><c- n>A</c-> <c- o>*</c-> <c- n>B</c-><c- p>)</c-> <c- o>+</c-> <c- p>(</c-><c- n>beta</c-> <c- o>*</c-> <c- n>C</c-><c- p>)</c-></code>, or <code class="highlight"><c- n>C</c-> <c- o>=</c-> <c- n>A</c-> <c- o>*</c-> <c- p>(</c-><c- n>alpha</c-> <c- o>*</c-> <c- n>B</c-><c- p>)</c-> <c- o>+</c-> <c- p>(</c-><c- n>beta</c-> <c- o>*</c-> <c- n>C</c-><c- p>)</c-></code>.</p>
   <p>"Textbook algorithms" includes optimizations commonly found in BLAS implementations.
This includes any available hardware acceleration,
as well as the locality and parallelism optimizations we describe below.
Thus, we think restricting generic implementations to textbook algorithms
will not overly limit implementers.</p>
   <p>The set of floating-point types currently has three members: <code class="highlight"><c- b>float</c-></code>, <code class="highlight"><c- b>double</c-></code>, and <code class="highlight"><c- b>long</c-> <c- b>double</c-></code>.
If a proposal like P1467R4 ("Extended floating-point types and standard names") is accepted,
it will grow to include implementation-specific types,
such as short or extended-precision floats.
This "future-proofs" our proposal in some sense,
though implementers will need to take care to avoid approximations
if the element type lacks the needed precision.</p>
   <h4 class="heading settled" data-level="11.6.7" id="reordering-sums-and-creating-temporaries"><span class="secno">11.6.7. </span><span class="content">Reordering sums and creating temporaries</span><a class="self-link" href="#reordering-sums-and-creating-temporaries"></a></h4>
   <p>Even textbook descriptions of linear algebra algorithms
presume the freedom to reorder sums and create temporary values.
Optimizations for memory locality and parallelism depend on this.
This freedom imposes requirements on algorithms' matrix and vector element types.</p>
   <p>We could get this freedom either by
limiting our proposal to the Standard’s current arithmetic types,
or by forbidding reordering and temporaries for types other than arithmetic types.
However, doing so would unnecessarily prevent straightforward optimizations
for small and fast types that act just like arithmetic types.
This includes so-called "short floats" such as bfloat16 or binary16,
extended-precision floating-point numbers, and fixed-point reals.
Some of these types may be implementation defined,
and others may be user-specified.
We intend to permit implementers to optimize for these types as well.
This motivates us to describe our algorithms' type requirements in a generic way.</p>
   <h5 class="heading settled" data-level="11.6.7.1" id="special-case-only-one-element-type"><span class="secno">11.6.7.1. </span><span class="content">Special case: Only one element type</span><a class="self-link" href="#special-case-only-one-element-type"></a></h5>
   <p>We find it easier to think about type requirements
by starting with the assumption that
all element and scalar types in algorithms are the same.
One can then generalize to input element type(s) that might differ
from the output element type and/or scalar result type.</p>
   <p>Optimizations for memory locality and parallelism
both create temporary values, and change the order of sums.
For example, reorganizing matrix data to reduce stride involves
making a temporary copy of a subset of the matrix,
and accumulating partial sums into the temporary copy.
Thus, both kinds of optimizations impose
a common set of requirements and assumptions on types.
Let <code class="highlight"><c- n>value_type</c-></code> be the output <code class="highlight"><c- n>mdspan</c-></code>'s <code class="highlight"><c- n>value_type</c-></code>.
Implementations may:</p>
   <ol>
    <li data-md>
     <p>create arbitrarily many objects of type <code class="highlight"><c- n>value_type</c-></code>,
value-initializing them or direct-initializing them
with any existing object of that type;</p>
    <li data-md>
     <p>perform sums in any order; or</p>
    <li data-md>
     <p>replace any value with the sum of that value
and a value-initialized <code class="highlight"><c- n>value_type</c-></code> object.</p>
   </ol>
   <p>Assumption (1) implies that the output value type is <code class="highlight"><c- n>semiregular</c-></code>.
Contrast with <strong>[algorithms.parallel.exec]</strong>:
"Unless otherwise stated,
implementations may make arbitrary copies of elements of type <code class="highlight"><c- n>T</c-></code>,
from sequences where <code class="highlight"><c- n>is_</c->­<c- n>trivially_</c->­<c- n>copy_</c->­<c- n>constructible_</c->­<c- n>v</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code> and <code class="highlight"><c- n>is_</c->­<c- n>trivially_</c->­<c- n>destructible_</c->­<c- n>v</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code> are true."
We omit the trivially constructible and destructible requirements here
and permit any <code class="highlight"><c- n>semiregular</c-></code> type.
Linear algebra algorithms assume mathematical properties
that let us impose more specific requirements than general parallel algorithms.
Nevertheless, implementations may want to enable optimizations
that create significant temporary storage
only if the value type is trivially constructible,
trivially destructible, and not too large.</p>
   <p>Regarding Assumption (2):
The freedom to compute sums in any order is not necessarily a type constraint.
Rather, it’s a right that the algorithm claims,
regardless of whether the type’s addition is associative or commutative.
For example, floating-point sums are not associative,
yet both parallelization and customary linear algebra optimizations
rely on reordering sums.
See the above "Value type constraints do not suffice to describe algorithm behavior" section
for a more detailed explanation.</p>
   <p>Regarding Assumption (3),
we do not actually say that
value-initialization produces a two-sided additive identity.
What matters is what the algorithm’s implementation may do,
not whether the type actually behaves in this way.</p>
   <h5 class="heading settled" data-level="11.6.7.2" id="general-case-multiple-input-element-types"><span class="secno">11.6.7.2. </span><span class="content">General case: Multiple input element types</span><a class="self-link" href="#general-case-multiple-input-element-types"></a></h5>
   <p>An important feature of P1673 is the ability to compute
with mixed matrix or vector element types.
For instance, <code class="highlight"><c- n>add</c-><c- p>(</c-><c- n>y</c-><c- p>,</c-> <c- n>scaled</c-><c- p>(</c-><c- n>alpha</c-><c- p>,</c-> <c- n>x</c-><c- p>),</c-> <c- n>z</c-><c- p>)</c-></code> implements the operation z = y + alpha*x,
an elementwise scaled vector sum.
The element types of the vectors x, y, and z could be all different,
and could differ from the type of alpha.</p>
   <h6 class="heading settled" data-level="11.6.7.2.1" id="accumulate-into-output-value-type"><span class="secno">11.6.7.2.1. </span><span class="content">Accumulate into output value type</span><a class="self-link" href="#accumulate-into-output-value-type"></a></h6>
   <p>Generic algorithms would use the output <code class="highlight"><c- n>mdspan</c-></code>'s <code class="highlight"><c- n>value_type</c-></code> to accumulate partial sums, and for any temporary results.
This is the analog of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>reduce</c-></code>'s scalar result type <code class="highlight"><c- n>T</c-></code>.
Implementations for floating-point types might accumulate into higher-precision temporaries,
or use other ways to increase accuracy when accumulating partial sums,
but the output <code class="highlight"><c- n>mdspan</c-></code>'s <code class="highlight"><c- n>value_type</c-></code> would still control accumulation behavior in general.</p>
   <h6 class="heading settled" data-level="11.6.7.2.2" id="proxy-references-or-expression-templates"><span class="secno">11.6.7.2.2. </span><span class="content">Proxy references or expression templates</span><a class="self-link" href="#proxy-references-or-expression-templates"></a></h6>
   <ol>
    <li data-md>
     <p>Proxy references: The input and/or output <code class="highlight"><c- n>mdspan</c-></code> might have an accessor
with a <code class="highlight"><c- n>reference</c-></code> type other than <code class="highlight"><c- n>element_type</c-><c- o>&amp;</c-></code>.
For example, the output <code class="highlight"><c- n>mdspan</c-></code> might have a value type <code class="highlight"><c- n>value_type</c-></code>,
but its <code class="highlight"><c- n>reference</c-></code> type might be <code class="highlight"><c- n>atomic_ref</c-><c- o>&lt;</c-><c- n>value_type</c-><c- o>></c-></code>.</p>
    <li data-md>
     <p>Expression templates: The element types themselves might have arithmetic operations
that defer the actual computation until the expression is assigned.
These "expression template" types typically hold
some kind of reference or pointer to their input arguments.</p>
   </ol>
   <p>Neither proxy references nor expression template types are <code class="highlight"><c- n>semiregular</c-></code>,
because they behave like references, not like values.
However, we can still require that their underlying value type be <code class="highlight"><c- n>semiregular</c-></code>.
For instance, the possiblity of proxy references just means that
we need to use the output <code class="highlight"><c- n>mdspan</c-></code>'s <code class="highlight"><c- n>value_type</c-></code> when constructing or value-initializing temporary values,
rather than trying to deduce the value type
from the type of an expression that indexes into the output <code class="highlight"><c- n>mdspan</c-></code>.
Expression templates just mean that we need to use the output <code class="highlight"><c- n>mdspan</c-></code>'s <code class="highlight"><c- n>value_type</c-></code> to construct or value-initialize temporaries,
rather than trying to deduce the temporaries' type
from the right-hand side of the expression.</p>
   <p>The z = y + alpha*x example above shows that some of the algorithms we propose
have multiple terms in a sum on the right-hand side of the expression
that defines the algorithm.
If algorithms have permission to rearrange the order of sums,
then they need to be able to break up such expressions into separate terms,
even if some of those expressions are expression templates.</p>
   <h4 class="heading settled" data-level="11.6.8" id="textbook-algorithm-description-in-semiring-terms"><span class="secno">11.6.8. </span><span class="content">"Textbook" algorithm description in semiring terms</span><a class="self-link" href="#textbook-algorithm-description-in-semiring-terms"></a></h4>
   <p>As we explain in the
"Value type constraints do not suffice to describe algorithm behavior" section above,
we deliberately constrain matrix and vector element types
to require associative addition.
This means that we do not, for instance, define concepts like "ring" or "group."
We cannot even speak of a single set of values
that would permit defining things like a "ring" or "group."
This is because our algorithms must handle mixed value types,
expression templates, and proxy references.
However, it may still be helpful to use mathematical language
to explain what we mean by "a textbook description of the algorithm."</p>
   <p>Most of the algorithms we propose only depend on addition and multiplication.
We describe these algorithms in terms of one or more mathematical expressions
on elements of a <em>semiring</em> with possibly noncommutative multiplication.
The only difference between a semiring and a ring
is that a semiring does not require all elements to have an additive inverse.
That is, addition is allowed, but not subtraction.
Implementers may apply any mathematical transformation to the expressions
that would give the same result for any semiring.</p>
   <h5 class="heading settled" data-level="11.6.8.1" id="why-a-semiring"><span class="secno">11.6.8.1. </span><span class="content">Why a semiring?</span><a class="self-link" href="#why-a-semiring"></a></h5>
   <p>We use a semiring because</p>
   <ol>
    <li data-md>
     <p>we generally want to reorder terms in sums,
but we do not want to order terms in products; and</p>
    <li data-md>
     <p>we do not want to assume that subtraction works.</p>
   </ol>
   <p>The first is because linear algebra computations are useful
for matrix or vector element types with noncommutative multiplication,
such as quaternions or matrices.
The second is because algebra operations might be useful for signed integers,
where a formulation using subtraction risks unexpected undefined behavior.</p>
   <h5 class="heading settled" data-level="11.6.8.2" id="semirings-and-testing"><span class="secno">11.6.8.2. </span><span class="content">Semirings and testing</span><a class="self-link" href="#semirings-and-testing"></a></h5>
   <p>It’s important that implementers be able to test our proposed algorithms
for custom element types, not just the built-in arithmetic types.
We don’t want to require hypothetical "exact real arithmetic" types
that take particular expertise to implement.
Instead, we propose testing with simple classes built out of unsigned integers.
This section is not part of our Standard Library proposal,
but we include it to give guidance to implementers
and to show that it’s feasible to test our proposal.</p>
   <h5 class="heading settled" data-level="11.6.8.3" id="commutative-multiplication"><span class="secno">11.6.8.3. </span><span class="content">Commutative multiplication</span><a class="self-link" href="#commutative-multiplication"></a></h5>
   <p>C++ unsigned integers implement commutative rings.
(Rings always have commutative addition;
a "commutative ring" has commutative multiplication as well.)
We may transform (say) <code class="highlight"><c- b>uint32_t</c-></code> into a commutative semiring
by wrapping it in a class that does not provide unary or binary <code class="highlight"><c- k>operator</c-><c- o>-</c-></code>.
Adding a "tag" template parameter to this class
would let implementers build tests for mixed element types.</p>
   <h5 class="heading settled" data-level="11.6.8.4" id="noncommutative-multiplication"><span class="secno">11.6.8.4. </span><span class="content">Noncommutative multiplication</span><a class="self-link" href="#noncommutative-multiplication"></a></h5>
   <p>The semiring of 2x2 matrices with element type a commutative semiring
is itself a semiring,
but with noncommutative multiplication.
This is a good way to build a noncommutative semiring for testing.</p>
   <h4 class="heading settled" data-level="11.6.9" id="summary"><span class="secno">11.6.9. </span><span class="content">Summary</span><a class="self-link" href="#summary"></a></h4>
   <ul>
    <li data-md>
     <p>Constraining the matrix and vector element types and scalar types in our functions
gives implementers the freedom to make QoI enhancements
without risking correctness.</p>
     <p>"Value type constraints do not suffice to describe algorithm behavior" section above,</p>
    <li data-md>
     <p>We think describing algorithms' behavior and implementation freedom
is more useful than mathematical concepts like "ring."
For example, we permit implementations to reorder sums,
but this does not mean that they assume sums are associative.</p>
    <li data-md>
     <p>We categorize different ways that implementers might like to change algorithms,
list categories we exclude and categories we permit,
and use the permitted categories to derive constraints
on the types of matrix and vector elements and scalar results.</p>
    <li data-md>
     <p>We explain how a semiring is a good way to talk about implementation freedom,
even though we do not think it is a good way to constrain types.
We then use the semiring description to explain how implementers
can test generic algorithms.</p>
   </ul>
   <h2 class="heading settled" data-level="12" id="future-work"><span class="secno">12. </span><span class="content">Future work</span><a class="self-link" href="#future-work"></a></h2>
   <p>Summary:</p>
   <ol>
    <li data-md>
     <p>Consider generalizing function parameters to take any type that implements the <code class="highlight"><c- n>get_mdspan</c-></code> customization point, including <code class="highlight"><c- n>mdarray</c-></code>.</p>
    <li data-md>
     <p>Add batched linear algebra overloads.</p>
   </ol>
   <h3 class="heading settled" data-level="12.1" id="generalize-function-parameters"><span class="secno">12.1. </span><span class="content">Generalize function parameters</span><a class="self-link" href="#generalize-function-parameters"></a></h3>
   <p>Our functions differ from the C++ Standard algorithms, in that they
take a concrete type <code class="highlight"><c- n>mdspan</c-></code> with template parameters, rather
than any type that satisfies a concept.  We think that the template
parameters of <code class="highlight"><c- n>mdspan</c-></code> fully describe the multidimensional
equivalent of a multipass iterator, and that "conceptification" of
multidimensional arrays would unnecessarily delay both this proposal
and P0009.</p>
   <p>In a future proposal, we may consider generalizing our function’s template
parameters, to permit any type besides <code class="highlight"><c- n>mdspan</c-></code> that implements
the <code class="highlight"><c- n>get_mdspan</c-></code> customization point, as long as the return value of <code class="highlight"><c- n>get_mdspan</c-></code> satisfies the current requirements. <code class="highlight"><c- n>get_mdspan</c-></code> would
return an <code class="highlight"><c- n>mdspan</c-></code> that views its argument’s data.</p>
   <p>The <code class="highlight"><c- n>mdarray</c-></code> class, proposed in <a href="https://wg21.link/p1684r0">P1684R0</a>, is the
container analog of <code class="highlight"><c- n>mdspan</c-></code>.  It is a new kind of container,
with the same copy behavior as containers like <code class="highlight"><c- n>vector</c-></code>.
It will be possible to get an <code class="highlight"><c- n>mdspan</c-></code> that views an <code class="highlight"><c- n>mdarray</c-></code>.
Previous versions of this proposal included function overloads that
took <code class="highlight"><c- n>mdarray</c-></code> directly.  The goals were user convenience, and
to avoid any potential overhead of conversion to <code class="highlight"><c- n>mdspan</c-></code>,
especially for very small matrices and vectors.  In a future revision
of P1684, <code class="highlight"><c- n>mdarray</c-></code> may implement a customization point <code class="highlight"><c- n>get_mdspan</c-></code> (final name yet to be decided).
This would let users use <code class="highlight"><c- n>mdarray</c-></code> directly in our functions.
This customization point approach would also simplify using our functions
with other matrix and vector types, such as those proposed by P1385R6.
Implementations may optionally add direct overloads of our functions
for <code class="highlight"><c- n>mdarray</c-></code> or other types.
This would address any concerns about overhead
of converting from <code class="highlight"><c- n>mdarray</c-></code> to <code class="highlight"><c- n>mdspan</c-></code>.</p>
   <h3 class="heading settled" data-level="12.2" id="batched-linear-algebra"><span class="secno">12.2. </span><span class="content">Batched linear algebra</span><a class="self-link" href="#batched-linear-algebra"></a></h3>
   <p>We plan to write a separate proposal that will add "batched" versions
of linear algebra functions to this proposal.  "Batched" linear
algebra functions solve many independent problems all at once, in a
single function call.  For discussion, see Section 6.2 of our
background paper <a href="https://wg21.link/p1417r0">P1417R0</a>.
Batched interfaces have the following advantages:</p>
   <ul>
    <li data-md>
     <p>They expose more parallelism and vectorization opportunities for
many small linear algebra operations.</p>
    <li data-md>
     <p>They are useful for many different fields, including machine
learning.</p>
    <li data-md>
     <p>Hardware vendors currently offer both hardware features and
optimized software libraries to support batched linear algebra.</p>
    <li data-md>
     <p>There is an ongoing <a href="http://icl.utk.edu/bblas/">interface standardization effort</a>,
in which we participate.</p>
   </ul>
   <p>The <code class="highlight"><c- n>mdspan</c-></code> data structure makes it easy to represent a batch
of linear algebra objects, and to optimize their data layout.</p>
   <p>With few exceptions, the extension of this proposal to support batched
operations will not require new functions or interface changes.  Only
the requirements on functions will change.  Output arguments can have
an additional rank; if so, then the leftmost extent will refer to the
batch dimension.  Input arguments may also have an additional rank to
match; if they do not, the function will use ("broadcast") the same
input argument for all the output arguments in the batch.</p>
   <h2 class="heading settled" data-level="13" id="data-structures-and-utilities-borrowed-from-other-proposals"><span class="secno">13. </span><span class="content">Data structures and utilities borrowed from other proposals</span><a class="self-link" href="#data-structures-and-utilities-borrowed-from-other-proposals"></a></h2>
   <h3 class="heading settled" data-level="13.1" id="mdspan"><span class="secno">13.1. </span><span class="content"><code class="highlight"><c- n>mdspan</c-></code></span><a class="self-link" href="#mdspan"></a></h3>
   <p>This proposal depends on P0009,
which proposes adding multidimensional arrays to the C++ Standard
Library.  P0009’s main class is <code class="highlight"><c- n>mdspan</c-></code>, which is a "view"
(in the sense of <code class="highlight"><c- n>span</c-></code>) of a multidimensional array.  The rank
(number of dimensions) is fixed at compile time.  Users may specify
some dimensions at run time and others at compile time; the type of
the <code class="highlight"><c- n>mdspan</c-></code> expresses this. <code class="highlight"><c- n>mdspan</c-></code> also has two
customization points:</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>Layout</c-></code> expresses the array’s memory layout: e.g., row-major (C++
style), column-major (Fortran style), or strided.  We use a custom <code class="highlight"><c- n>Layout</c-></code> later in this paper to implement a "transpose view" of an
existing <code class="highlight"><c- n>mdspan</c-></code>.</p>
    <li data-md>
     <p><code class="highlight"><c- n>Accessor</c-></code> defines the storage handle (i.e., <code class="highlight"><c- n>pointer</c-></code>) stored in
the <code class="highlight"><c- n>mdspan</c-></code>, as well as the reference type returned by its access
operator.  This is an extension point for modifying how access
happens, for example by using <code class="highlight"><c- n>atomic_ref</c-></code> to get atomic access to
every element.  We use custom <code class="highlight"><c- n>Accessor</c-></code>s later in this paper to
implement "scaled views" and "conjugated views" of an existing <code class="highlight"><c- n>mdspan</c-></code>.</p>
   </ul>
   <h3 class="heading settled" data-level="13.2" id="new-mdspan-layouts-in-this-proposal"><span class="secno">13.2. </span><span class="content">New <code class="highlight"><c- n>mdspan</c-></code> layouts in this proposal</span><a class="self-link" href="#new-mdspan-layouts-in-this-proposal"></a></h3>
   <p>Our proposal uses the layout mapping policy of <code class="highlight"><c- n>mdspan</c-></code> in order
to represent different matrix and vector data layouts.  Layout mapping
policies as described by P0009 have three basic properties:</p>
   <ul>
    <li data-md>
     <p>Unique</p>
    <li data-md>
     <p>Contiguous</p>
    <li data-md>
     <p>Strided</p>
   </ul>
   <p>P0009 includes three different layouts -- <code class="highlight"><c- n>layout_left</c-></code>, <code class="highlight"><c- n>layout_right</c-></code>, and <code class="highlight"><c- n>layout_stride</c-></code> -- all of which are unique and
strided.  Only <code class="highlight"><c- n>layout_left</c-></code> and <code class="highlight"><c- n>layout_right</c-></code> are contiguous.</p>
   <p>This proposal includes the following additional layouts:</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>layout_blas_general</c-></code>, a generalization of <code class="highlight"><c- n>layout_left</c-></code> and <code class="highlight"><c- n>layout_right</c-></code> that describes the layout used by General (GE) matrix "type"; and</p>
    <li data-md>
     <p><code class="highlight"><c- n>layout_blas_packed</c-></code>, which describes the layout used by the BLAS' Symmetric
Packed (SP), Hermitian Packed (HP), and Triangular Packed (TP)
"types."</p>
   </ul>
   <p>These layouts have "tag" template parameters that control their
properties; see below.</p>
   <p>We do not include layouts for unpacked "types," such as Symmetric
(SY), Hermitian (HE), and Triangular (TR).  P1674 explains our
reasoning.  In summary: Their actual layout -- the arrangement of
matrix elements in memory -- is the same as General.  The only
differences are constraints on what entries of the matrix algorithms
may access, and assumptions about the matrix’s mathematical
properties.  Trying to express those constraints or assumptions as
"layouts" or "accessors" violates the spirit (and sometimes the law)
of <code class="highlight"><c- n>mdspan</c-></code>.  We address these different matrix types with
different function names.</p>
   <p>The packed matrix "types" do describe actual arrangements of matrix
elements in memory that are not the same as in General.  This is why
we provide <code class="highlight"><c- n>layout_blas_packed</c-></code>.  Note that <code class="highlight"><c- n>layout_blas_packed</c-></code> is
the first addition to the layouts in P0009 that is neither always
unique, nor always strided.</p>
   <p>Algorithms cannot be written generically if they permit output
arguments with nonunique layouts.  Nonunique output arguments require
specialization of the algorithm to the layout, since there’s no way to
know generically at compile time what indices map to the same matrix
element.  Thus, we will impose the following rule: Any <code class="highlight"><c- n>mdspan</c-></code> output argument to our functions must always have unique layout
(<code class="highlight"><c- n>is_always_unique</c-><c- p>()</c-></code> is <code class="highlight">true</code>), unless otherwise specified.</p>
   <p>Some of our functions explicitly require outputs with specific
nonunique layouts.  This includes low-rank updates to symmetric or
Hermitian matrices.</p>
   <h2 class="heading settled" data-level="14" id="acknowledgments"><span class="secno">14. </span><span class="content">Acknowledgments</span><a class="self-link" href="#acknowledgments"></a></h2>
   <p>Sandia National Laboratories is a multimission laboratory managed and
operated by National Technology &amp; Engineering Solutions of Sandia,
LLC, a wholly owned subsidiary of Honeywell International, Inc., for
the U.S. Department of Energy’s National Nuclear Security
Administration under contract DE-NA0003525.</p>
   <p>Special thanks to Bob Steagall and Guy Davidson for boldly leading the
charge to add linear algebra to the C++ Standard Library, and for many
fruitful discussions.  Thanks also to Andrew Lumsdaine for his
pioneering efforts and history lessons.
In addition, I very much appreciate feedback from Davis Herring
on constraints wording.</p>
   <h2 class="heading settled" data-level="15" id="references"><span class="secno">15. </span><span class="content">References</span><a class="self-link" href="#references"></a></h2>
   <h3 class="heading settled" data-level="15.1" id="references-by-coathors"><span class="secno">15.1. </span><span class="content">References by coathors</span><a class="self-link" href="#references-by-coathors"></a></h3>
   <ul>
    <li data-md>
     <p>G. Ballard, E. Carson, J. Demmel, M. Hoemmen, N. Knight, and
O. Schwartz, <a href="https://doi.org/10.1017/S0962492914000038">"Communication lower bounds and optimal algorithms for numerical linear algebra,"</a>, <em>Acta Numerica</em>, Vol. 23, May 2014, pp. 1-155.</p>
    <li data-md>
     <p>C. Trott, D. S. Hollman, D. Lebrun-Grande, M. Hoemmen, D. Sunderland,
H. C. Edwards, B. A. Lelbach, M. Bianco, B. Sander, A. Iliopoulos,
J. Michopoulos, and N. Liber,
"<code class="highlight"><c- n>mdspan</c-></code>," <a href="https://wg21.link/p0009r14">P0009R14</a>,
Nov. 2021.</p>
    <li data-md>
     <p>G. Davidson, M. Hoemmen, D. S. Hollman, B. Steagall, and C. Trott, <a href="https://wg21.link/p1891r0">P1891R0</a>, Oct. 2019.</p>
    <li data-md>
     <p>M. Hoemmen, D. S. Hollman, and C. Trott, "Evolving a Standard C++
Linear Algebra Library from the BLAS," <a href="https://wg21.link/p1674">P1674R0</a>, Jun. 2019.</p>
    <li data-md>
     <p>M. Hoemmen, J. Badwaik, M. Brucher, A. Iliopoulos, and
J. Michopoulos, "Historical lessons for C++ linear algebra library
standardization," <a href="https://wg21.link/p1417r0">P1417R0</a>,
Jan. 2019.</p>
    <li data-md>
     <p>M. Hoemmen, D. S. Hollman, C. Jabot, I. Muerte, and C. Trott,
"Multidimensional subscript operator," <a href="https://wg21.link/p2128r6">P2128R6</a>, Sep. 2021.</p>
    <li data-md>
     <p>D. S. Hollman, C. Trott, M. Hoemmen, and D. Sunderland,
"<code class="highlight"><c- n>mdarray</c-></code>: An Owning Multidimensional Array Analog of <code class="highlight"><c- n>mdspan</c-></code>", <a href="https://isocpp.org/files/papers/P1684R0.pdf">P1684R0</a>,
Jun. 2019.</p>
    <li data-md>
     <p>D. S. Hollman, C. Kohlhoff, B. A. Lelbach, J. Hoberock, G. Brown, and
M. Dominiak, "A General Property Customization Mechanism," <a href="https://wg21.link/p1393r0">P1393R0</a>, Jan. 2019.</p>
   </ul>
   <h3 class="heading settled" data-level="15.2" id="other-references"><span class="secno">15.2. </span><span class="content">Other references</span><a class="self-link" href="#other-references"></a></h3>
   <ul>
    <li data-md>
     <p>E. Anderson,
"Algorithm 978: Safe Scaling in the Level 1 BLAS," <em>ACM Transactions on Mathematical Software</em>,
Vol. 44, pp. 1-28, 2017.</p>
    <li data-md>
     <p><a href="http://netlib.org/blas/blast-forum/blas-report.pdf">"Basic Linear Algebra Subprograms Technical (BLAST) Forum Standard,"</a> <em>International Journal of High Performance Applications and Supercomputing</em>,
Vol. 16, No. 1, Spring 2002.</p>
    <li data-md>
     <p>L. S. Blackford, J. Demmel, J. Dongarra, I. Duff, S. Hammarling,
G. Henry, M. Heroux, L. Kaufman, A. Lumsdaine, A. Petitet, R. Pozo,
K. Remington, and R. C. Whaley, <a href="https://doi.org/10.1145/567806.567807">"An updated set of basic linear algebra subprograms (BLAS),"</a> <em>ACM Transactions on Mathematical Software</em>,
Vol. 28, No. 2, Jun. 2002, pp. 135-151.</p>
    <li data-md>
     <p>J. L. Blue,
"A Portable Fortran Program to Find the Euclidean Norm of a Vector," <em>ACM Transactions on Mathematical Software</em>, Vol. 4, pp. 15-23, 1978.</p>
    <li data-md>
     <p>E. Chow and A. Patel,
"Fine-Grained Parallel Incomplete LU Factorization",
SIAM J. Sci. Comput., 37(2), C169–C193, 2015.</p>
    <li data-md>
     <p>G. Davidson and B. Steagall, "A proposal to add linear algebra
support to the C++ standard library," <a href="https://wg21.link/p1385r6">P1385R6</a>, Mar. 2020.</p>
    <li data-md>
     <p>B. Dawes, H. Hinnant, B. Stroustrup, D. Vandevoorde, and M. Wong,
"Direction for ISO C++," <a href="https://wg21.link/p0939r4">P0939R4</a>,
Oct. 2019.</p>
    <li data-md>
     <p>J. Demmel, "Applied Numerical Linear Algebra,"
Society for Industrial and Applied Mathematics,
Philadelphia, PA, 1997,
ISBN 0-89871-389-7.</p>
    <li data-md>
     <p>J. Demmel, I. Dumitriu, and O. Holtz,
"Fast linear algebra is stable," <em>Numerische Mathematik</em> 108 (59-91), 2007.</p>
    <li data-md>
     <p>J. Demmel and H. D. Nguyen,
"Fast Reproducible Floating-Point Summation,"
2013 IEEE 21st Symposium on Computer Arithmetic,
2013, pp. 163-172, doi: 10.1109/ARITH.2013.9.</p>
    <li data-md>
     <p>J. Dongarra, R. Pozo, and D. Walker, "LAPACK++: A Design Overview of
Object-Oriented Extensions for High Performance Linear Algebra," in
Proceedings of Supercomputing '93, IEEE Computer Society Press,
1993, pp. 162-171.</p>
    <li data-md>
     <p>M. Gates, P. Luszczek, A. Abdelfattah, J. Kurzak, J. Dongarra,
K. Arturov, C. Cecka, and C. Freitag, <a href="https://www.icl.utk.edu/files/publications/2017/icl-utk-1031-2017.pdf">"C++ API for BLAS and LAPACK,"</a> SLATE Working Notes, Innovative Computing Laboratory,
University of Tennessee Knoxville, Feb. 2018.</p>
    <li data-md>
     <p>K. Goto and R. A. van de Geijn, <a href="https://doi.org/10.1145/1356052.1356053">"Anatomy of high-performance matrix multiplication,"</a>, <em>ACM Transactions on Mathematical Software</em> (TOMS),
Vol. 34, No. 3, May 2008.</p>
    <li data-md>
     <p>J. Hoberock, "Integrating Executors with Parallel Algorithms," <a href="https://wg21.link/p1019r2">P1019R2</a>, Jan. 2019.</p>
    <li data-md>
     <p>N. A. Josuttis, "The C++ Standard Library: A Tutorial and Reference,"
Addison-Wesley, 1999.</p>
    <li data-md>
     <p>M. Kretz, "Data-Parallel Vector Types &amp; Operations," <a href="https://wg21.link/p0214r9">P0214R9</a>, Mar. 2018.</p>
    <li data-md>
     <p>G. Strang,
"Introduction to Linear Algebra," 5th Edition,
Wellesley - Cambridge Press, 2016, ISBN 978-0-9802327-7-6, x+574 pages.</p>
    <li data-md>
     <p>D. Vandevoorde and N. A. Josuttis,
"C++ Templates: The Complete Guide," Addison-Wesley Professional, 2003.</p>
   </ul>
   <h2 class="heading settled" data-level="16" id="wording"><span class="secno">16. </span><span class="content">Wording</span><a class="self-link" href="#wording"></a></h2>
   <blockquote>
    <p>Text in blockquotes is not proposed wording, but rather instructions for generating proposed wording.
The � character is used to denote a placeholder section number which the editor shall determine.
First, apply all wording from P0009R14.
(This proposal is a "rebase" atop the changes proposed by P0009R14.)
At the end of Table � ("Numerics library summary") in <em>[numerics.general]</em>, add the following: [linalg], Linear algebra, <code class="highlight"><c- o>&lt;</c-><c- n>linalg</c-><c- o>></c-></code>.
At the end of <em>[numerics]</em>, add all the material that follows.</p>
   </blockquote>
   <h3 class="heading settled" data-level="16.1" id="header-linalg-synopsis-linalgsyn"><span class="secno">16.1. </span><span class="content">Header <code class="highlight"><c- o>&lt;</c-><c- n>linalg</c-><c- o>></c-></code> synopsis [linalg.syn]</span><a class="self-link" href="#header-linalg-synopsis-linalgsyn"></a></h3>
<pre class="language-c++ highlight"><c- n>namespace</c-> <c- n>std</c-><c- o>::</c-><c- n>linalg</c-> <c- p>{</c->
<c- c1>// [linalg.tags.order], storage order tags</c->
<c- k>struct</c-> <c- nc>column_major_t</c-><c- p>;</c->
<c- kr>inline</c-> <c- n>constexpr</c-> <c- n>column_major_t</c-> <c- n>column_major</c-><c- p>;</c->
<c- k>struct</c-> <c- nc>row_major_t</c-><c- p>;</c->
<c- kr>inline</c-> <c- n>constexpr</c-> <c- n>row_major_t</c-> <c- n>row_major</c-><c- p>;</c->

<c- c1>// [linalg.tags.triangle], triangle tags</c->
<c- k>struct</c-> <c- nc>upper_triangle_t</c-><c- p>;</c->
<c- kr>inline</c-> <c- n>constexpr</c-> <c- n>upper_triangle_t</c-> <c- n>upper_triangle</c-><c- p>;</c->
<c- k>struct</c-> <c- nc>lower_triangle_t</c-><c- p>;</c->
<c- kr>inline</c-> <c- n>constexpr</c-> <c- n>lower_triangle_t</c-> <c- n>lower_triangle</c-><c- p>;</c->

<c- c1>// [linalg.tags.diagonal], diagonal tags</c->
<c- k>struct</c-> <c- nc>implicit_unit_diagonal_t</c-><c- p>;</c->
<c- kr>inline</c-> <c- n>constexpr</c-> <c- n>implicit_unit_diagonal_t</c-> <c- n>implicit_unit_diagonal</c-><c- p>;</c->
<c- k>struct</c-> <c- nc>explicit_diagonal_t</c-><c- p>;</c->
<c- kr>inline</c-> <c- n>constexpr</c-> <c- n>explicit_diagonal_t</c-> <c- n>explicit_diagonal</c-><c- p>;</c->

<c- c1>// [linalg.layouts.general], class template layout_blas_general</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>StorageOrder</c-><c- o>></c->
<c- n>class</c-> <c- n>layout_blas_general</c-><c- p>;</c->

<c- c1>// [linalg.layouts.packed], class template layout_blas_packed</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>StorageOrder</c-><c- o>></c->
<c- n>class</c-> <c- n>layout_blas_packed</c-><c- p>;</c->

<c- c1>// [linalg.scaled.accessor_scaled], class template accessor_scaled</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ScalingFactor</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Accessor</c-><c- o>></c->
<c- n>class</c-> <c- n>accessor_scaled</c-><c- p>;</c->

<c- c1>// [linalg.scaled.scaled], scaled in-place transformation</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ScalingFactor</c-><c- p>,</c->
         <c- n>class</c-> <c- n>ElementType</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Extents</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Layout</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Accessor</c-><c- o>></c->
<c- d>/* see-below */</c->
<c- n>scaled</c-><c- p>(</c->
  <c- k>const</c-> <c- n>ScalingFactor</c-><c- o>&amp;</c-> <c- n>s</c-><c- p>,</c->
  <c- k>const</c-> <c- n>mdspan</c-><c- o>&lt;</c-><c- n>ElementType</c-><c- p>,</c-> <c- n>Extents</c-><c- p>,</c-> <c- n>Layout</c-><c- p>,</c-> <c- n>Accessor</c-><c- o>>&amp;</c-> <c- n>a</c-><c- p>);</c->

<c- c1>// [linalg.conj.accessor_conjugate], class template accessor_conjugate</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Accessor</c-><c- o>></c->
<c- n>class</c-> <c- n>accessor_conjugate</c-><c- p>;</c->

<c- c1>// [linalg.conj.conjugated], conjugated in-place transformation</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ElementType</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Extents</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Layout</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Accessor</c-><c- o>></c->
<c- d>/* see-below */</c->
<c- n>conjugated</c-><c- p>(</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- n>ElementType</c-><c- p>,</c-> <c- n>Extents</c-><c- p>,</c-> <c- n>Layout</c-><c- p>,</c-> <c- n>Accessor</c-><c- o>></c-> <c- n>a</c-><c- p>);</c->

<c- c1>// [linalg.transp.layout_transpose], class template layout_transpose</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Layout</c-><c- o>></c->
<c- n>class</c-> <c- n>layout_transpose</c-><c- p>;</c->

<c- c1>// [linalg.transp.transposed], transposed in-place transformation</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ElementType</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Extents</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Layout</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Accessor</c-><c- o>></c->
<c- d>/* see-below */</c->
<c- n>transposed</c-><c- p>(</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- n>ElementType</c-><c- p>,</c-> <c- n>Extents</c-><c- p>,</c-> <c- n>Layout</c-><c- p>,</c-> <c- n>Accessor</c-><c- o>></c-> <c- n>a</c-><c- p>);</c->

<c- c1>// [linalg.conj_transp],</c->
<c- c1>// conjugated transposed in-place transformation</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ElementType</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Extents</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Layout</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Accessor</c-><c- o>></c->
<c- d>/* see-below */</c->
<c- n>conjugate_transposed</c-><c- p>(</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- n>ElementType</c-><c- p>,</c-> <c- n>Extents</c-><c- p>,</c-> <c- n>Layout</c-><c- p>,</c-> <c- n>Accessor</c-><c- o>></c-> <c- n>a</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas1.givens.lartg], compute Givens rotation</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Real</c-><c- o>></c->
<c- b>void</c-> <c- n>givens_rotation_setup</c-><c- p>(</c-><c- k>const</c-> <c- n>Real</c-> <c- n>a</c-><c- p>,</c->
                           <c- k>const</c-> <c- n>Real</c-> <c- n>b</c-><c- p>,</c->
                           <c- n>Real</c-><c- o>&amp;</c-> <c- n>c</c-><c- p>,</c->
                           <c- n>Real</c-><c- o>&amp;</c-> <c- n>s</c-><c- p>,</c->
                           <c- n>Real</c-><c- o>&amp;</c-> <c- n>r</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Real</c-><c- o>></c->
<c- b>void</c-> <c- n>givens_rotation_setup</c-><c- p>(</c-><c- k>const</c-> <c- k>complex</c-><c- o>&lt;</c-><c- n>Real</c-><c- o>>&amp;</c-> <c- n>a</c-><c- p>,</c->
                           <c- k>const</c-> <c- k>complex</c-><c- o>&lt;</c-><c- n>Real</c-><c- o>>&amp;</c-> <c- n>a</c-><c- p>,</c->
                           <c- n>Real</c-><c- o>&amp;</c-> <c- n>c</c-><c- p>,</c->
                           <c- k>complex</c-><c- o>&lt;</c-><c- n>Real</c-><c- o>>&amp;</c-> <c- n>s</c-><c- p>,</c->
                           <c- k>complex</c-><c- o>&lt;</c-><c- n>Real</c-><c- o>>&amp;</c-> <c- n>r</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas1.givens.rot], apply computed Givens rotation</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>inout_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Real</c-><c- o>></c->
<c- b>void</c-> <c- n>givens_rotation_apply</c-><c- p>(</c->
  <c- n>inout_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- k>const</c-> <c- n>Real</c-> <c- n>c</c-><c- p>,</c->
  <c- k>const</c-> <c- n>Real</c-> <c- n>s</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Real</c-><c- o>></c->
<c- b>void</c-> <c- n>givens_rotation_apply</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>inout_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- k>const</c-> <c- n>Real</c-> <c- n>c</c-><c- p>,</c->
  <c- k>const</c-> <c- n>Real</c-> <c- n>s</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>inout_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Real</c-><c- o>></c->
<c- b>void</c-> <c- n>givens_rotation_apply</c-><c- p>(</c->
  <c- n>inout_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- k>const</c-> <c- n>Real</c-> <c- n>c</c-><c- p>,</c->
  <c- k>const</c-> <c- k>complex</c-><c- o>&lt;</c-><c- n>Real</c-><c- o>></c-> <c- n>s</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Real</c-><c- o>></c->
<c- b>void</c-> <c- n>givens_rotation_apply</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>inout_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- k>const</c-> <c- n>Real</c-> <c- n>c</c-><c- p>,</c->
  <c- k>const</c-> <c- k>complex</c-><c- o>&lt;</c-><c- n>Real</c-><c- o>></c-> <c- n>s</c-><c- p>);</c->
<c- p>}</c->

<c- c1>// [linalg.algs.blas1.swap], swap elements</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>inout_object_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_object_2_t</c-><c- o>></c->
<c- b>void</c-> <c- n>swap_elements</c-><c- p>(</c-><c- n>inout_object_1_t</c-> <c- n>x</c-><c- p>,</c->
                   <c- n>inout_object_2_t</c-> <c- n>y</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_object_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_object_2_t</c-><c- o>></c->
<c- b>void</c-> <c- n>swap_elements</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                   <c- n>inout_object_1_t</c-> <c- n>x</c-><c- p>,</c->
                   <c- n>inout_object_2_t</c-> <c- n>y</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas1.scal], multiply elements by scalar</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Scalar</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_object_t</c-><c- o>></c->
<c- b>void</c-> <c- n>scale</c-><c- p>(</c-><c- k>const</c-> <c- n>Scalar</c-> <c- n>alpha</c-><c- p>,</c->
           <c- n>inout_object_t</c-> <c- n>obj</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Scalar</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_object_t</c-><c- o>></c->
<c- b>void</c-> <c- n>scale</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
           <c- k>const</c-> <c- n>Scalar</c-> <c- n>alpha</c-><c- p>,</c->
           <c- n>inout_object_t</c-> <c- n>obj</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas1.copy], copy elements</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_object_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_object_t</c-><c- o>></c->
<c- b>void</c-> <c- n>copy</c-><c- p>(</c-><c- n>in_object_t</c-> <c- n>x</c-><c- p>,</c->
          <c- n>out_object_t</c-> <c- n>y</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_object_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_object_t</c-><c- o>></c->
<c- b>void</c-> <c- n>copy</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
          <c- n>in_object_t</c-> <c- n>x</c-><c- p>,</c->
          <c- n>out_object_t</c-> <c- n>y</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas1.add], add elementwise</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_object_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_object_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_object_t</c-><c- o>></c->
<c- b>void</c-> <c- n>add</c-><c- p>(</c-><c- n>in_object_1_t</c-> <c- n>x</c-><c- p>,</c->
         <c- n>in_object_2_t</c-> <c- n>y</c-><c- p>,</c->
         <c- n>out_object_t</c-> <c- n>z</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_object_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_object_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_object_t</c-><c- o>></c->
<c- b>void</c-> <c- n>add</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
         <c- n>in_object_1_t</c-> <c- n>x</c-><c- p>,</c->
         <c- n>in_object_2_t</c-> <c- n>y</c-><c- p>,</c->
         <c- n>out_object_t</c-> <c- n>z</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas1.dot],</c->
<c- c1>// dot product of two vectors</c->

<c- c1>// [linalg.algs.blas1.dot.dotu],</c->
<c- c1>// nonconjugated dot product of two vectors</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>dot</c-><c- p>(</c-><c- n>in_vector_1_t</c-> <c- n>v1</c-><c- p>,</c->
      <c- n>in_vector_2_t</c-> <c- n>v2</c-><c- p>,</c->
      <c- n>T</c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>dot</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
      <c- n>in_vector_1_t</c-> <c- n>v1</c-><c- p>,</c->
      <c- n>in_vector_2_t</c-> <c- n>v2</c-><c- p>,</c->
      <c- n>T</c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>dot</c-><c- p>(</c-><c- n>in_vector_1_t</c-> <c- n>v1</c-><c- p>,</c->
         <c- n>in_vector_2_t</c-> <c- n>v2</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>dot</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
         <c- n>in_vector_1_t</c-> <c- n>v1</c-><c- p>,</c->
         <c- n>in_vector_2_t</c-> <c- n>v2</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->

<c- c1>// [linalg.algs.blas1.dot.dotc],</c->
<c- c1>// conjugated dot product of two vectors</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>dotc</c-><c- p>(</c-><c- n>in_vector_1_t</c-> <c- n>v1</c-><c- p>,</c->
       <c- n>in_vector_2_t</c-> <c- n>v2</c-><c- p>,</c->
       <c- n>T</c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>dotc</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
       <c- n>in_vector_1_t</c-> <c- n>v1</c-><c- p>,</c->
       <c- n>in_vector_2_t</c-> <c- n>v2</c-><c- p>,</c->
       <c- n>T</c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>dotc</c-><c- p>(</c-><c- n>in_vector_1_t</c-> <c- n>v1</c-><c- p>,</c->
          <c- n>in_vector_2_t</c-> <c- n>v2</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>dotc</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
          <c- n>in_vector_1_t</c-> <c- n>v1</c-><c- p>,</c->
          <c- n>in_vector_2_t</c-> <c- n>v2</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->

<c- c1>// [linalg.algs.blas1.ssq],</c->
<c- c1>// Scaled sum of squares of a vector’s elements</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- k>struct</c-> <c- nc>sum_of_squares_result</c-> <c- p>{</c->
  <c- n>T</c-> <c- n>scaling_factor</c-><c- p>;</c->
  <c- n>T</c-> <c- n>scaled_sum_of_squares</c-><c- p>;</c->
<c- p>};</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>sum_of_squares_result</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- n>vector_sum_of_squares</c-><c- p>(</c->
  <c- n>in_vector_t</c-> <c- n>v</c-><c- p>,</c->
  <c- n>sum_of_squares_result</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- n>init</c-><c- p>);</c->
<c- n>sum_of_squares_result</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- n>vector_sum_of_squares</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>v</c-><c- p>,</c->
  <c- n>sum_of_squares_result</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- n>init</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas1.nrm2],</c->
<c- c1>// Euclidean norm of a vector</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>vector_norm2</c-><c- p>(</c-><c- n>in_vector_t</c-> <c- n>v</c-><c- p>,</c->
               <c- n>T</c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>vector_norm2</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
               <c- n>in_vector_t</c-> <c- n>v</c-><c- p>,</c->
               <c- n>T</c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>vector_norm2</c-><c- p>(</c-><c- n>in_vector_t</c-> <c- n>v</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>vector_norm2</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                  <c- n>in_vector_t</c-> <c- n>v</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->

<c- c1>// [linalg.algs.blas1.asum],</c->
<c- c1>// sum of absolute values of vector elements</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>vector_abs_sum</c-><c- p>(</c-><c- n>in_vector_t</c-> <c- n>v</c-><c- p>,</c->
                 <c- n>T</c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>vector_abs_sum</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                 <c- n>in_vector_t</c-> <c- n>v</c-><c- p>,</c->
                 <c- n>T</c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>vector_abs_sum</c-><c- p>(</c-><c- n>in_vector_t</c-> <c- n>v</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>vector_abs_sum</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                    <c- n>in_vector_t</c-> <c- n>v</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->

<c- c1>// [linalg.algs.blas1.iamax],</c->
<c- c1>// index of maximum absolute value of vector elements</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_t</c-><c- o>></c->
<c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>idx_abs_max</c-><c- p>(</c-><c- n>in_vector_t</c-> <c- n>v</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- o>></c->
<c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>idx_abs_max</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>v</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas1.matfrobnorm],</c->
<c- c1>// Frobenius norm of a matrix</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>matrix_frob_norm</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>T</c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>matrix_frob_norm</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>T</c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>matrix_frob_norm</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>matrix_frob_norm</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->

<c- c1>// [linalg.algs.blas1.matonenorm],</c->
<c- c1>// One norm of a matrix</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>matrix_one_norm</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>T</c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>matrix_one_norm</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>T</c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>matrix_one_norm</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>matrix_one_norm</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->

<c- c1>// [linalg.algs.blas1.matinfnorm],</c->
<c- c1>// Infinity norm of a matrix</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>matrix_inf_norm</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>T</c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>matrix_inf_norm</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>T</c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>matrix_inf_norm</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>matrix_inf_norm</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->

<c- c1>// [linalg.algs.blas2.gemv],</c->
<c- c1>// general matrix-vector product</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_vector_product</c-><c- p>(</c-><c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                           <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
                           <c- n>out_vector_t</c-> <c- n>y</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_vector_product</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                           <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                           <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
                           <c- n>out_vector_t</c-> <c- n>y</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_vector_product</c-><c- p>(</c-><c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                           <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
                           <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
                           <c- n>out_vector_t</c-> <c- n>z</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_vector_product</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                           <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                           <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
                           <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
                           <c- n>out_vector_t</c-> <c- n>z</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas2.symv],</c->
<c- c1>// symmetric matrix-vector product</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_vector_product</c-><c- p>(</c-><c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                                     <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
                                     <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
                                     <c- n>out_vector_t</c-> <c- n>y</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_vector_product</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                                     <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                                     <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
                                     <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
                                     <c- n>out_vector_t</c-> <c- n>y</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_vector_product</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- n>out_vector_t</c-> <c- n>z</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_vector_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- n>out_vector_t</c-> <c- n>z</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas2.hemv],</c->
<c- c1>// Hermitian matrix-vector product</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_vector_product</c-><c- p>(</c-><c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                                     <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
                                     <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
                                     <c- n>out_vector_t</c-> <c- n>y</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_vector_product</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                                     <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                                     <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
                                     <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
                                     <c- n>out_vector_t</c-> <c- n>y</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_vector_product</c-><c- p>(</c-><c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                                     <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
                                     <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
                                     <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
                                     <c- n>out_vector_t</c-> <c- n>z</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_vector_product</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                                     <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                                     <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
                                     <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
                                     <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
                                     <c- n>out_vector_t</c-> <c- n>z</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas2.trmv],</c->
<c- c1>// Triangular matrix-vector product</c->

<c- c1>// [linalg.algs.blas2.trmv.ov],</c->
<c- c1>// Overwriting triangular matrix-vector product</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_vector_product</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>out_vector_t</c-> <c- n>y</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_vector_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>out_vector_t</c-> <c- n>y</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas2.trmv.in-place],</c->
<c- c1>// In-place triangular matrix-vector product</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_vector_product</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_vector_t</c-> <c- n>y</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas2.trmv.up],</c->
<c- c1>// Updating triangular matrix-vector product</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_vector_product</c-><c- p>(</c-><c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                                      <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
                                      <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
                                      <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
                                      <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
                                      <c- n>out_vector_t</c-> <c- n>z</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_vector_product</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                                      <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                                      <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
                                      <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
                                      <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
                                      <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
                                      <c- n>out_vector_t</c-> <c- n>z</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas2.trsv],</c->
<c- c1>// Solve a triangular linear system</c->

<c- c1>// [linalg.algs.blas2.trsv.not-in-place],</c->
<c- c1>// Solve a triangular linear system, not in place</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_vector_solve</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>b</c-><c- p>,</c->
  <c- n>out_vector_t</c-> <c- n>x</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_vector_solve</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>b</c-><c- p>,</c->
  <c- n>out_vector_t</c-> <c- n>x</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas2.trsv.in-place],</c->
<c- c1>// Solve a triangular linear system, in place</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_vector_solve</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_vector_t</c-> <c- n>b</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_vector_solve</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_vector_t</c-> <c- n>b</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas2.rank1.geru],</c->
<c- c1>// nonconjugated rank-1 matrix update</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_rank_1_update</c-><c- p>(</c->
  <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_rank_1_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas2.rank1.gerc],</c->
<c- c1>// conjugated rank-1 matrix update</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_rank_1_update_c</c-><c- p>(</c->
  <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_rank_1_update_c</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas2.rank1.syr],</c->
<c- c1>// symmetric rank-1 matrix update</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_rank_1_update</c-><c- p>(</c->
  <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_rank_1_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_rank_1_update</c-><c- p>(</c->
  <c- n>T</c-> <c- n>alpha</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_rank_1_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>T</c-> <c- n>alpha</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas2.rank1.her],</c->
<c- c1>// Hermitian rank-1 matrix update</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_rank_1_update</c-><c- p>(</c->
  <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_rank_1_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_rank_1_update</c-><c- p>(</c->
  <c- n>T</c-> <c- n>alpha</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_rank_1_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>T</c-> <c- n>alpha</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas2.rank2.syr2],</c->
<c- c1>// symmetric rank-2 matrix update</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_rank_2_update</c-><c- p>(</c->
  <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_rank_2_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas2.rank2.her2],</c->
<c- c1>// Hermitian rank-2 matrix update</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_rank_2_update</c-><c- p>(</c->
  <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_rank_2_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas3.gemm],</c->
<c- c1>// general matrix-matrix product</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_product</c-><c- p>(</c-><c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
                    <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
                    <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_product</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                    <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
                    <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
                    <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_product</c-><c- p>(</c-><c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
                    <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
                    <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
                    <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_product</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                    <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
                    <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
                    <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
                    <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas3.symm],</c->
<c- c1>// symmetric matrix-matrix product</c->

<c- c1>// [linalg.algs.blas3.symm.ov.left],</c->
<c- c1>// overwriting symmetric matrix-matrix left product</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_left_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_left_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas3.symm.ov.right],</c->
<c- c1>// overwriting symmetric matrix-matrix right product</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_right_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_right_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas3.symm.up.left],</c->
<c- c1>// updating symmetric matrix-matrix left product</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_left_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_left_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas3.symm.up.right],</c->
<c- c1>// updating symmetric matrix-matrix right product</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_right_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_right_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas3.hemm],</c->
<c- c1>// Hermitian matrix-matrix product</c->

<c- c1>// [linalg.algs.blas3.hemm.ov.left],</c->
<c- c1>// overwriting Hermitian matrix-matrix left product</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_left_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_left_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas3.hemm.ov.right],</c->
<c- c1>// overwriting Hermitian matrix-matrix right product</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_right_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_right_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas3.hemm.up.left],</c->
<c- c1>// updating Hermitian matrix-matrix left product</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_left_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_left_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas3.hemm.up.right],</c->
<c- c1>// updating Hermitian matrix-matrix right product</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_right_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_right_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas3.trmm],</c->
<c- c1>// triangular matrix-matrix product</c->

<c- c1>// [linalg.algs.blas3.trmm.ov.left],</c->
<c- c1>// overwriting triangular matrix-matrix left product</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_left_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_left_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_left_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_left_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas3.trmm.ov.right],</c->
<c- c1>// overwriting triangular matrix-matrix right product</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_right_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_right_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_right_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_right_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas3.trmm.up.left],</c->
<c- c1>// updating triangular matrix-matrix left product</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_left_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_left_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->

<c- c1>// [linalg.algs.blas3.trmm.up.right],</c->
<c- c1>// updating triangular matrix-matrix right product</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_right_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_right_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->

<c- c1>// [linalg.alg.blas3.rank-k.syrk],</c->
<c- c1>// rank-k symmetric matrix update</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_rank_k_update</c-><c- p>(</c->
  <c- n>T</c-> <c- n>alpha</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- p>,</c->
         <c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_rank_k_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>T</c-> <c- n>alpha</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->

<c- c1>// [linalg.alg.blas3.rank-k.herk],</c->
<c- c1>// rank-k Hermitian matrix update</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_rank_k_update</c-><c- p>(</c->
  <c- n>T</c-> <c- n>alpha</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_rank_k_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>T</c-> <c- n>alpha</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->

<c- c1>// [linalg.alg.blas3.rank2k.syr2k],</c->
<c- c1>// rank-2k symmetric matrix update</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_rank_2k_update</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_rank_2k_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->

<c- c1>// [linalg.alg.blas3.rank2k.her2k],</c->
<c- c1>// rank-2k Hermitian matrix update</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_rank_2k_update</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_rank_2k_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->

<c- c1>// [linalg.alg.blas3.trsm],</c->
<c- c1>// solve multiple triangular linear systems</c->

<c- c1>// [linalg.alg.blas3.trsm.left],</c->
<c- c1>// solve multiple triangular linear systems</c->
<c- c1>// with triangular matrix on the left</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_matrix_left_solve</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>X</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_matrix_left_solve</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>X</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_matrix_left_solve</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>B</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_matrix_left_solve</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>B</c-><c- p>);</c->

<c- c1>// [linalg.alg.blas3.trsm.right],</c->
<c- c1>// solve multiple triangular linear systems</c->
<c- c1>// with triangular matrix on the right</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_matrix_right_solve</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>X</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_matrix_right_solve</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>X</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_matrix_right_solve</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>B</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_matrix_right_solve</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>B</c-><c- p>);</c->
<c- p>}</c->
</pre>
   <h3 class="heading settled" data-level="16.2" id="requirements-linalgreqs"><span class="secno">16.2. </span><span class="content">Requirements [linalg.reqs]</span><a class="self-link" href="#requirements-linalgreqs"></a></h3>
   <h4 class="heading settled" data-level="16.2.1" id="value-and-reference-requirements-linalgreqsval"><span class="secno">16.2.1. </span><span class="content">Value and reference requirements [linalg.reqs.val]</span><a class="self-link" href="#value-and-reference-requirements-linalgreqsval"></a></h4>
   <p>This clause lists the minimum requirements for all algorithms and classes in <strong>[linalg]</strong>,
and for the following types:</p>
   <ul>
    <li data-md>
     <p>for any input or output <code class="highlight"><c- n>mdspan</c-></code> parameter(s) of any algorithm or method in <strong>[linalg]</strong>,
the parameter(s)' <code class="highlight"><c- n>value_type</c-></code> and <code class="highlight"><c- n>reference</c-></code> type aliases;</p>
    <li data-md>
     <p>the <code class="highlight"><c- n>Scalar</c-></code> template parameter (if any) of any algorithm or class in <strong>[linalg]</strong>;</p>
    <li data-md>
     <p>the <code class="highlight"><c- n>T</c-></code> template parameter of any algorithm in <strong>[linalg]</strong> with a <code class="highlight"><c- n>T</c-> <c- n>init</c-></code> parameter; and</p>
    <li data-md>
     <p>the template parameter of <code class="highlight"><c- n>sum_of_squares_result</c-></code>.</p>
   </ul>
   <p>In this clause, we refer to these types as <em>linear algebra value types</em>.
These type requirements are parameterized by the algorithm or method using the type.
Each algorithm or method using the type has one or more associated mathematical expressions
that defines the algorithm’s or method’s behavior.
For each algorithm or method,
its mathematical expression(s) are either explicitly stated as such,
or are implicitly stated in the algorithm’s or method’s description.
The requirements below will refer to those mathematical expression(s).</p>
   <p><em>[Note:</em> This notion of parameterizing requirements on a mathematical expression
generalizes <em>GENERALIZED_SUM</em>.
--<em>end note]</em></p>
   <p>All of the following requirements presume that the algorithm’s
asymptotic complexity requirements, if any, are satisfied.</p>
   <ol>
    <li data-md>
     <p>Any linear algebra value type
meets the requirements of <code class="highlight"><c- n>semiregular</c-></code>.</p>
    <li data-md>
     <p>The algorithm or method may perform read-only access
on any input or output <code class="highlight"><c- n>mdspan</c-></code> arbitrarily many times.</p>
    <li data-md>
     <p>The algorithm or method may make arbitrary many objects
of any linear algebra value type,
value-initializing or direct-initializing them
with any existing object of that type.</p>
    <li data-md>
     <p>The algorithm or method may assign arbitrarily many times
to any reference
resulting from a valid output <code class="highlight"><c- n>mdspan</c-></code> access.</p>
    <li data-md>
     <p>If the algorithm’s or method’s mathematical expression
uses division and possibly also
addition, subtraction, and multiplication,
then the algorithm or method
evaluates the mathematical expression
using a sequence of evaluations of <code class="highlight"><c- o>*</c-></code>, <code class="highlight"><c- o>*=</c-></code>, <code class="highlight"><c- o>/</c-></code>, <code class="highlight"><c- o>/=</c-></code>, <code class="highlight"><c- o>+</c-></code>, <code class="highlight"><c- o>+=</c-></code>, unary <code class="highlight"><c- o>-</c-></code>, binary <code class="highlight"><c- o>-</c-></code>, <code class="highlight"><c- o>-=</c-></code>,
and <code class="highlight"><c- o>=</c-></code> operators
that would produce the correct result
when operating on elements of a field
with noncommutative multiplication.
(We interpret <code class="highlight"><c- n>a</c-> <c- o>/</c-> <c- n>b</c-></code> as <code class="highlight"><c- n>a</c-></code> times the multiplicative inverse of <code class="highlight"><c- n>b</c-></code>.)
Any addend,
any subtrahend,
any partial sum of addends in any order
(treating any difference as a sum with the second term negated),
any factor,
any partial product of factors respecting their order in the mathematical expression,
any numerator,
any denominator,
and any assignment in the mathematical expression
shall be well formed.</p>
    <li data-md>
     <p>Otherwise, if the algorithm’s or method’s mathematical expression
uses subtraction and possibly also
addition and multiplication,
then the algorithm or method
evaluates the mathematical expression
using a sequence of evaluations of <code class="highlight"><c- o>*</c-></code>, <code class="highlight"><c- o>*=</c-></code>, <code class="highlight"><c- o>+</c-></code>, <code class="highlight"><c- o>+=</c-></code>,
unary <code class="highlight"><c- o>-</c-></code>, binary <code class="highlight"><c- o>-</c-></code>, <code class="highlight"><c- o>-=</c-></code>,
and <code class="highlight"><c- o>=</c-></code> operators
that would produce the correct result
when operating on elements of a ring
with noncommutative multiplication.
Any addend,
any subtrahend,
any partial sum of addends in any order
(treating any difference as a sum with the second term negated),
any factor,
any partial product of factors respecting their order in the mathematical expression,
and any assignment in the mathematical expression
shall be well formed.</p>
    <li data-md>
     <p>Otherwise, if the algorithm’s or method’s mathematical expression
uses multiplication and possibly also addition,
then the algorithm or method
evaluates the mathematical expression
using a sequence of evaluations of <code class="highlight"><c- o>*</c-></code>, <code class="highlight"><c- o>*=</c-></code>, <code class="highlight"><c- o>+</c-></code>, <code class="highlight"><c- o>+=</c-></code>, and <code class="highlight"><c- o>=</c-></code> operators
that would produce the correct result
when operating on elements of a semiring
with noncommutative multiplication.
Any addend,
any partial sum of addends in any order,
any factor,
any partial product of factors respecting their order in the mathematical expression,
and any assignment in the mathematical expression
shall be well formed.</p>
    <li data-md>
     <p>Otherwise, if the algorithm’s or method’s mathematical expression
uses addition,
then the algorithm or method evaluates the mathematical expression
using a sequence of evaluations of <code class="highlight"><c- o>+</c-></code>, <code class="highlight"><c- o>+=</c-></code>, and <code class="highlight"><c- o>=</c-></code> operators
that would produce the correct result
when operating on elements of a commutative semigroup.
Any addend,
any partial sum of addends in any order,
and any assignment in the mathematical expression
shall be well formed.</p>
    <li data-md>
     <p>If the algorithm’s or method’s mathematical expression includes any of the following:</p>
     <p>a. <code class="highlight"><c- n>conj</c-><c- p>(</c-><c- n>z</c-><c- p>)</c-></code> for some expression <code class="highlight"><c- n>z</c-></code>,</p>
     <p>b. <code class="highlight"><c- n>abs</c-><c- p>(</c-><c- n>x</c-><c- p>)</c-></code> for some expression <code class="highlight"><c- n>x</c-></code>, or</p>
     <p>c. <code class="highlight"><c- n>sqrt</c-><c- p>(</c-><c- n>x</c-><c- p>)</c-></code> for some expression <code class="highlight"><c- n>x</c-></code>,</p>
     <p>but otherwise conforms to case (5), (6), (7), or (8),
then the relevant case (5), (6), (7), or (8) applies.
In addition, any of the above subexpressions that appear
in the algorithm’s or method’s mathematical expression
shall be well formed.
However, if the mathematical expression includes <code class="highlight"><c- n>conj</c-><c- p>(</c-><c- n>z</c-><c- p>)</c-></code> for an expression <code class="highlight"><c- n>z</c-></code> that is <em>not</em> convertible to <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- n>R</c-><c- o>></c-></code> for some <code class="highlight"><c- n>R</c-></code>,
then the <code class="highlight"><c- n>conj</c-><c- p>(</c-><c- n>z</c-><c- p>)</c-></code> expression is interpreted as <code class="highlight"><c- n>z</c-></code> for this requirement.</p>
    <li data-md>
     <p>If the algorithm or method has an output <code class="highlight"><c- n>mdspan</c-></code>,
then all addends (or subtrahends, if applicable)
in the algorithm’s or method’s mathematical expression
are assignable and convertible to the output <code class="highlight"><c- n>mdspan</c-></code>'s <code class="highlight"><c- n>value_type</c-></code>.</p>
    <li data-md>
     <p>The algorithm or method may reorder addends and partial sums
in its mathematical expression arbitrarily. <em>[Note:</em> Factors in each product are not reordered;
multiplication is not necessarily commutative.
--<em>end note]</em></p>
    <li data-md>
     <p>The algorithm or method may replace any value
with the sum of that value
and a value-initialized object
of any input or output <code class="highlight"><c- n>mdspan</c-></code>'s <code class="highlight"><c- n>value_type</c-></code>.</p>
    <li data-md>
     <p>If the algorithm or method has a <code class="highlight"><c- n>T</c-> <c- n>init</c-></code> parameter,
then the algorithm or method may replace any value
with the sum of that value
and a value-initialized object of type <code class="highlight"><c- n>T</c-></code>.</p>
   </ol>
   <h4 class="heading settled" data-level="16.2.2" id="requirements-for-algorithms-and-methods-on-floating-point-values-linalgreqsflpt"><span class="secno">16.2.2. </span><span class="content">Requirements for algorithms and methods on floating-point values [linalg.reqs.flpt]</span><a class="self-link" href="#requirements-for-algorithms-and-methods-on-floating-point-values-linalgreqsflpt"></a></h4>
   <p>For all algorithms and classes in <strong>[linalg]</strong>, suppose that</p>
   <ul>
    <li data-md>
     <p>all input and output <code class="highlight"><c- n>mdspan</c-></code> have <code class="highlight"><c- n>value_type</c-></code> a floating-point type,</p>
    <li data-md>
     <p>any <code class="highlight"><c- n>Scalar</c-></code> template argument has a floating-point type, and</p>
    <li data-md>
     <p>any argument corresponding to the <code class="highlight"><c- n>T</c-> <c- n>init</c-></code> parameter has a floating-point type.</p>
   </ul>
   <p>Then, algorithms and classes' methods may do the following:</p>
   <ol>
    <li data-md>
     <p>compute floating-point sums in any way that improves their accuracy for arbitrary input;</p>
    <li data-md>
     <p>perform arithmetic operations other than those
in the algorithm’s or method’s mathematical expression,
in order to improve performance or accuracy; and</p>
    <li data-md>
     <p>use approximations (that might not be exact even if computing with real numbers),
instead of computations that would be exact
if it were possible to compute without rounding error;</p>
   </ol>
   <p>as long as</p>
   <ol>
    <li data-md>
     <p>the algorithm or method satisfies the complexity requirements; and</p>
    <li data-md>
     <p>the algorithm or method is <em>logarithmically stable</em>,
in the sense of (Demmel 2007).</p>
   </ol>
   <p><em>[Note:</em> Strassen’s algorithm for matrix-matrix multiply is an example of a logarithmically stable algorithm.
--<em>end note]</em></p>
   <h3 class="heading settled" data-level="16.3" id="tag-classes-linalgtags"><span class="secno">16.3. </span><span class="content">Tag classes [linalg.tags]</span><a class="self-link" href="#tag-classes-linalgtags"></a></h3>
   <h4 class="heading settled" data-level="16.3.1" id="storage-order-tags-linalgtagsorder"><span class="secno">16.3.1. </span><span class="content">Storage order tags [linalg.tags.order]</span><a class="self-link" href="#storage-order-tags-linalgtagsorder"></a></h4>
<pre class="language-c++ highlight"><c- k>struct</c-> <c- nc>column_major_t</c-> <c- p>{</c-> <c- p>};</c->
<c- kr>inline</c-> <c- n>constexpr</c-> <c- n>column_major_t</c-> <c- n>column_major</c-> <c- o>=</c-> <c- p>{</c-> <c- p>};</c->

<c- k>struct</c-> <c- nc>row_major_t</c-> <c- p>{</c-> <c- p>};</c->
<c- kr>inline</c-> <c- n>constexpr</c-> <c- n>row_major_t</c-> <c- n>row_major</c-> <c- o>=</c-> <c- p>{</c-> <c- p>};</c->
</pre>
   <p><code class="highlight"><c- n>column_major_t</c-></code> indicates a column-major order, and <code class="highlight"><c- n>row_major_t</c-></code> indicates a row-major order.  The interpretation of each depends on
the specific layout that uses the tag.  See <code class="highlight"><c- n>layout_blas_general</c-></code> and <code class="highlight"><c- n>layout_blas_packed</c-></code> below.</p>
   <h4 class="heading settled" data-level="16.3.2" id="triangle-tags-linalgtagstriangle"><span class="secno">16.3.2. </span><span class="content">Triangle tags [linalg.tags.triangle]</span><a class="self-link" href="#triangle-tags-linalgtagstriangle"></a></h4>
   <p>Some linear algebra algorithms distinguish between the "upper
triangle," "lower triangle," and "diagonal" of a matrix.</p>
   <ul>
    <li data-md>
     <p>The <em>upper triangle</em> of a matrix <code class="highlight"><c- n>A</c-></code> is the set of all elements of <code class="highlight"><c- n>A</c-></code> accessed by <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> with <code class="highlight"><c- n>i</c-></code> >= <code class="highlight"><c- n>j</c-></code>.</p>
    <li data-md>
     <p>The <em>lower triangle</em> of <code class="highlight"><c- n>A</c-></code> is the set of all elements of <code class="highlight"><c- n>A</c-></code> accessed by <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> with <code class="highlight"><c- n>i</c-></code> &lt;= <code class="highlight"><c- n>j</c-></code>.</p>
    <li data-md>
     <p>The <em>diagonal</em> is the set of all elements of <code class="highlight"><c- n>A</c-></code> accessed by <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code>.  It is included in both the upper triangle and the lower
triangle.</p>
   </ul>
<pre class="language-c++ highlight"><c- k>struct</c-> <c- nc>upper_triangle_t</c-> <c- p>{</c-> <c- p>};</c->
<c- kr>inline</c-> <c- n>constexpr</c-> <c- n>upper_triangle_t</c-> <c- n>upper_triangle</c-> <c- o>=</c-> <c- p>{</c-> <c- p>};</c->

<c- k>struct</c-> <c- nc>lower_triangle_t</c-> <c- p>{</c-> <c- p>};</c->
<c- kr>inline</c-> <c- n>constexpr</c-> <c- n>lower_triangle_t</c-> <c- n>lower_triangle</c-> <c- o>=</c-> <c- p>{</c-> <c- p>};</c->
</pre>
   <p>These tag classes specify whether algorithms and other users of a
matrix (represented as an <code class="highlight"><c- n>mdspan</c-></code>) should
access the upper triangle (<code class="highlight"><c- n>upper_triangular_t</c-></code>) or lower triangle
(<code class="highlight"><c- n>lower_triangular_t</c-></code>) of the matrix.  This is also subject to the
restrictions of <code class="highlight"><c- n>implicit_unit_diagonal_t</c-></code> if that tag is also
applied; see below.</p>
   <h4 class="heading settled" data-level="16.3.3" id="diagonal-tags-linalgtagsdiagonal"><span class="secno">16.3.3. </span><span class="content">Diagonal tags [linalg.tags.diagonal]</span><a class="self-link" href="#diagonal-tags-linalgtagsdiagonal"></a></h4>
<pre class="language-c++ highlight"><c- k>struct</c-> <c- nc>implicit_unit_diagonal_t</c-> <c- p>{</c-> <c- p>};</c->
<c- kr>inline</c-> <c- n>constexpr</c-> <c- n>implicit_unit_diagonal_t</c->
  <c- n>implicit_unit_diagonal</c-> <c- o>=</c-> <c- p>{</c-> <c- p>};</c->

<c- k>struct</c-> <c- nc>explicit_diagonal_t</c-> <c- p>{</c-> <c- p>};</c->
<c- kr>inline</c-> <c- n>constexpr</c-> <c- n>explicit_diagonal_t</c-> <c- n>explicit_diagonal</c-> <c- o>=</c-> <c- p>{</c-> <c- p>};</c->
</pre>
   <p>These tag classes specify what algorithms and other users of a matrix
should assume about the diagonal entries of the matrix, and whether
algorithms and users of the matrix should access those diagonal
entries explicitly.</p>
   <p>The <code class="highlight"><c- n>implicit_unit_diagonal_t</c-></code> tag indicates two things:</p>
   <ul>
    <li data-md>
     <p>the function will never access the <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>i</c-></code> element of the matrix,
and</p>
    <li data-md>
     <p>the matrix has a diagonal of ones (a "unit diagonal").</p>
   </ul>
   <p>The tag <code class="highlight"><c- n>explicit_diagonal_t</c-></code> indicates that algorithms and other
users of the viewer may access the matrix’s diagonal entries directly.</p>
   <h3 class="heading settled" data-level="16.4" id="layouts-for-general-and-packed-matrix-types-linalglayouts"><span class="secno">16.4. </span><span class="content">Layouts for general and packed matrix types [linalg.layouts]</span><a class="self-link" href="#layouts-for-general-and-packed-matrix-types-linalglayouts"></a></h3>
   <h4 class="heading settled" data-level="16.4.1" id="layout_blas_general-linalglayoutsgeneral"><span class="secno">16.4.1. </span><span class="content"><code class="highlight"><c- n>layout_blas_general</c-></code> [linalg.layouts.general]</span><a class="self-link" href="#layout_blas_general-linalglayoutsgeneral"></a></h4>
   <p><code class="highlight"><c- n>layout_blas_general</c-></code> is an <code class="highlight"><c- n>mdspan</c-></code> layout mapping policy.  Its <code class="highlight"><c- n>StorageOrder</c-></code> template parameter determines whether the matrix’s data
layout is column major or row major.</p>
   <p><code class="highlight"><c- n>layout_blas_general</c-><c- o>&lt;</c-><c- n>column_major_t</c-><c- o>></c-></code> represents a column-major matrix
layout, where the stride between consecutive rows is always one, and
the stride between consecutive columns may be greater than or equal to
the number of rows. <em>[Note:</em> This is a generalization of <code class="highlight"><c- n>layout_left</c-></code>. --<em>end note]</em></p>
   <p><code class="highlight"><c- n>layout_blas_general</c-><c- o>&lt;</c-><c- n>row_major_t</c-><c- o>></c-></code> represents a row-major matrix
layout, where the stride between consecutive rows may be greater than
or equal to the number of columns, and the stride between consecutive
columns is always one. <em>[Note:</em> This is a generalization of <code class="highlight"><c- n>layout_right</c-></code>. --<em>end note]</em></p>
   <p><em>[Note:</em></p>
   <p><code class="highlight"><c- n>layout_blas_general</c-></code> represents exactly the data layout assumed by
the General (GE) matrix type in the BLAS' C binding.  It has two
advantages:</p>
   <ol>
    <li data-md>
     <p>Unlike <code class="highlight"><c- n>layout_left</c-></code> and <code class="highlight"><c- n>layout_right</c-></code>, any "submatrix" (subspan
of consecutive rows and consecutive columns) of a matrix with <code class="highlight"><c- n>layout_blas_general</c-><c- o>&lt;</c-><c- n>StorageOrder</c-><c- o>></c-></code> layout also has <code class="highlight"><c- n>layout_blas_general</c-><c- o>&lt;</c-><c- n>StorageOrder</c-><c- o>></c-></code> layout.</p>
    <li data-md>
     <p>Unlike <code class="highlight"><c- n>layout_stride</c-></code>, it always has compile-time unit stride in
one of the matrix’s two extents.</p>
   </ol>
   <p>BLAS functions call the possibly nonunit stride of the matrix the
"leading dimension" of that matrix.  For example, a BLAS function
argument corresponding to the leading dimension of the matrix <code class="highlight"><c- n>A</c-></code> is
called <code class="highlight"><c- n>LDA</c-></code>, for "leading dimension of the matrix A."</p>
   <p>--<em>end note]</em></p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>StorageOrder</c-><c- o>></c->
<c- n>class</c-> <c- n>layout_blas_general</c-> <c- p>{</c->
<c- nl>public</c-><c- p>:</c->
  <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Extents</c-><c- o>></c->
  <c- k>struct</c-> <c- nc>mapping</c-> <c- p>{</c->
  <c- nl>private</c-><c- p>:</c->
    <c- n>Extents</c-> <c- n>extents_</c-><c- p>;</c-> <c- c1>// exposition only</c->
    <c- k>const</c-> <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c-> <c- n>stride_</c-><c- p>{};</c-> <c- c1>// exposition only</c->

  <c- nl>public</c-><c- p>:</c->
    <c- n>constexpr</c-> <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>Extents</c-><c- o>&amp;</c-> <c- n>e</c-><c- p>,</c->
      <c- k>const</c-> <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c-> <c- n>s</c-><c- p>);</c->

    <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
    <c- n>constexpr</c-> <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>e</c-><c- p>)</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c->
    <c- n>operator</c-><c- p>()</c-> <c- p>(</c-><c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c-> <c- n>i</c-><c- p>,</c->
                <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c-> <c- n>j</c-><c- p>)</c-> <c- k>const</c-><c- p>;</c->

    <c- n>constexpr</c-> <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c->
    <c- n>required_span_size</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c->
    <c- n>stride</c-><c- p>(</c-><c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c-> <c- n>r</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
    <c- b>bool</c-> <c- n>operator</c-><c- o>==</c-><c- p>(</c-><c- k>const</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>m</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
    <c- b>bool</c-> <c- n>operator</c-><c- o>!=</c-><c- p>(</c-><c- k>const</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>m</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- n>Extents</c-> <c- nf>extents</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_unique</c-><c- p>();</c->
    <c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_contiguous</c-><c- p>();</c->
    <c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_strided</c-><c- p>();</c->

    <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_unique</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
    <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_contiguous</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
    <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_strided</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
  <c- p>};</c->
<c- p>};</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>StorageOrder</c-></code> is either <code class="highlight"><c- n>column_major_t</c-></code> or <code class="highlight"><c- n>row_major_t</c-></code>.</p>
      <li data-md>
       <p><code class="highlight"><c- n>Extents</c-></code> is a specialization of <code class="highlight"><c- n>extents</c-></code>.</p>
      <li data-md>
       <p><code class="highlight"><c- n>Extents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals 2.</p>
     </ul>
   </ul>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- nf>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>Extents</c-><c- o>&amp;</c-> <c- n>e</c-><c- p>,</c->
  <c- k>const</c-> <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c-> <c- n>s</c-><c- p>);</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p>If <code class="highlight"><c- n>StorageOrder</c-></code> is <code class="highlight"><c- n>column_major_t</c-></code>,
then <code class="highlight"><c- n>s</c-></code> is greater than or equal to <code class="highlight"><c- n>e</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>Otherwise, if <code class="highlight"><c- n>StorageOrder</c-></code> is <code class="highlight"><c- n>row_major_t</c-></code>,
then <code class="highlight"><c- n>s</c-></code> is greater than or equal to <code class="highlight"><c- n>e</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Effects:</em> Initializes <code class="highlight"><c- n>extents_</c-></code> with <code class="highlight"><c- n>e</c-></code>, and initializes <code class="highlight"><c- n>stride_</c-></code> with <code class="highlight"><c- n>s</c-></code>.</p>
   </ul>
   <p><em>[Note:</em></p>
   <p>The BLAS Standard requires that the stride be one if the corresponding
matrix dimension is zero.  We do not impose this requirement here,
because it is specific to the BLAS.  if an implementation dispatches
to a BLAS function, then the implementation must impose the
requirement at run time.</p>
   <p>--<em>end note]</em></p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
<c- n>constexpr</c-> <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>e</c-><c- p>)</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>OtherExtents</c-></code> is a specialization of <code class="highlight"><c- n>extents</c-></code>.</p>
      <li data-md>
       <p><code class="highlight"><c- n>OtherExtents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals 2.</p>
     </ul>
    <li data-md>
     <p><em>Effects:</em> Initializes <code class="highlight"><c- n>extents_</c-></code> with <code class="highlight"><c- n>m</c-><c- p>.</c-><c- n>extents_</c-></code>, and initializes <code class="highlight"><c- n>stride_</c-></code> with <code class="highlight"><c- n>m</c-><c- p>.</c-><c- n>stride_</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c->
<c- n>operator</c-><c- p>()</c-> <c- p>(</c-><c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c-> <c- n>i</c-><c- p>,</c->
            <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c-> <c- n>j</c-><c- p>)</c-> <c- k>const</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p>0 ≤ <code class="highlight"><c- n>i</c-></code> &lt; <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, and</p>
      <li data-md>
       <p>0 ≤ <code class="highlight"><c- n>j</c-></code> &lt; <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Returns:</em></p>
     <ul>
      <li data-md>
       <p>If <code class="highlight"><c- n>StorageOrder</c-></code> is <code class="highlight"><c- n>column_major_t</c-></code>, then <code class="highlight"><c- n>i</c-> <c- o>+</c-> <c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-><c- o>*</c-><c- n>j</c-></code>;</p>
      <li data-md>
       <p>else, if <code class="highlight"><c- n>StorageOrder</c-></code> is <code class="highlight"><c- n>row_major_t</c-></code>, then <code class="highlight"><c- n>stride</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-><c- o>*</c-><c- n>i</c-> <c- o>+</c-> <c- n>j</c-></code>.</p>
     </ul>
   </ul>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
<c- b>bool</c-> <c- n>operator</c-><c- o>==</c-><c- p>(</c-><c- k>const</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>m</c-><c- p>)</c-> <c- k>const</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Constraints:</em> <code class="highlight"><c- n>OtherExtents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals <code class="highlight"><c- n>rank</c-><c- p>()</c-></code>.</p>
    <li data-md>
     <p><em>Returns:</em> <code class="highlight">true</code> if and only if for 0 ≤ <code class="highlight"><c- n>r</c-></code> &lt; <code class="highlight"><c- n>rank</c-><c- p>()</c-></code>, <code class="highlight"><c- n>m</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> and <code class="highlight"><c- n>m</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>stride</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
<c- b>bool</c-> <c- n>operator</c-><c- o>!=</c-><c- p>(</c-><c- k>const</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>m</c-><c- p>)</c-> <c- k>const</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Constraints:</em> <code class="highlight"><c- n>OtherExtents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals <code class="highlight"><c- n>rank</c-><c- p>()</c-></code>.</p>
    <li data-md>
     <p><em>Returns:</em> <code class="highlight">true</code> if and only if
there exists <code class="highlight"><c- n>r</c-></code> with 0 ≤ <code class="highlight"><c- n>r</c-></code> &lt; <code class="highlight"><c- n>rank</c-><c- p>()</c-></code> such that <code class="highlight"><c- n>m</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> does not equal <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> or <code class="highlight"><c- n>m</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> does not equal <code class="highlight"><c- n>stride</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c->
<c- n>stride</c-><c- p>(</c-><c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c-> <c- n>r</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Returns:</em></p>
     <ul>
      <li data-md>
       <p>If <code class="highlight"><c- n>StorageOrder</c-></code> is <code class="highlight"><c- n>column_major_t</c-></code>, <code class="highlight"><c- n>stride_</c-></code> if <code class="highlight"><c- n>r</c-></code> equals 1, else 1;</p>
      <li data-md>
       <p>else, if <code class="highlight"><c- n>StorageOrder</c-></code> is <code class="highlight"><c- n>row_major_t</c-></code>, <code class="highlight"><c- n>stride_</c-></code> if <code class="highlight"><c- n>r</c-></code> equals 0, else 1.</p>
     </ul>
   </ul>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c->
<c- n>required_span_size</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Returns:</em> <code class="highlight"><c- n>stride</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-><c- o>*</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>Extents</c-> <c- nf>extents</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- n>extents_</c-><c- p>;</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_unique</c-><c- p>();</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Returns:</em> <code class="highlight">true</code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_contiguous</c-><c- p>();</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Returns:</em> <code class="highlight">false</code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_strided</c-><c- p>();</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Returns:</em> <code class="highlight">true</code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_unique</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Returns:</em> <code class="highlight">true</code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_contiguous</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Returns:</em></p>
     <ul>
      <li data-md>
       <p>If <code class="highlight"><c- n>StorageOrder</c-></code> is <code class="highlight"><c- n>column_major_t</c-></code>,
then <code class="highlight">true</code> if <code class="highlight"><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, else <code class="highlight">false</code>;</p>
      <li data-md>
       <p>else, if <code class="highlight"><c- n>StorageOrder</c-></code> is <code class="highlight"><c- n>row_major_t</c-></code>,
then <code class="highlight">true</code> if <code class="highlight"><c- n>stride</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>, else <code class="highlight">false</code>.</p>
     </ul>
   </ul>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_strided</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Returns:</em> <code class="highlight">true</code>.</p>
   </ul>
   <h4 class="heading settled" data-level="16.4.2" id="layout_blas_packed-linalglayoutspacked"><span class="secno">16.4.2. </span><span class="content"><code class="highlight"><c- n>layout_blas_packed</c-></code> [linalg.layouts.packed]</span><a class="self-link" href="#layout_blas_packed-linalglayoutspacked"></a></h4>
   <p><code class="highlight"><c- n>layout_blas_packed</c-></code> is an <code class="highlight"><c- n>mdspan</c-></code> layout mapping policy that
represents a square matrix that stores only the entries in one
triangle, in a packed contiguous format.  Its <code class="highlight"><c- n>Triangle</c-></code> template
parameter determines whether an <code class="highlight"><c- n>mdspan</c-></code> with this layout stores
the upper or lower triangle of the matrix.  Its <code class="highlight"><c- n>StorageOrder</c-></code> template parameter determines whether the layout packs the matrix’s
elements in column-major or row-major order.</p>
   <p>A <code class="highlight"><c- n>StorageOrder</c-></code> of <code class="highlight"><c- n>column_major_t</c-></code> indicates column-major ordering.
This packs matrix elements starting with the leftmost (least column
index) column, and proceeding column by column, from the top entry
(least row index).</p>
   <p>A <code class="highlight"><c- n>StorageOrder</c-></code> of <code class="highlight"><c- n>row_major_t</c-></code> indicates row-major ordering.  This
packs matrix elements starting with the topmost (least row index) row,
and proceeding row by row, from the leftmost (least column index)
entry.</p>
   <p><em>[Note:</em></p>
   <p><code class="highlight"><c- n>layout_blas_packed</c-></code> describes the data layout used by the BLAS'
Symmetric Packed (SP), Hermitian Packed (HP), and Triangular Packed
(TP) matrix types.</p>
   <p>If <code class="highlight"><c- n>transposed</c-></code>'s input has layout <code class="highlight"><c- n>layout_blas_packed</c-></code>, the
return type also has layout <code class="highlight"><c- n>layout_blas_packed</c-></code>, but with opposite <code class="highlight"><c- n>Triangle</c-></code> and <code class="highlight"><c- n>StorageOrder</c-></code>.  For example, the transpose of a packed
column-major upper triangle, is a packed row-major lower triangle.</p>
   <p>--<em>end note]</em></p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>StorageOrder</c-><c- o>></c->
<c- n>class</c-> <c- n>layout_blas_packed</c-> <c- p>{</c->
<c- nl>public</c-><c- p>:</c->
  <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Extents</c-><c- o>></c->
  <c- k>struct</c-> <c- nc>mapping</c-> <c- p>{</c->
  <c- nl>private</c-><c- p>:</c->
    <c- n>Extents</c-> <c- n>extents_</c-><c- p>;</c-> <c- c1>// exposition only</c->

  <c- nl>public</c-><c- p>:</c->
    <c- n>constexpr</c-> <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>Extents</c-><c- o>&amp;</c-> <c- n>e</c-><c- p>);</c->

    <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
    <c- n>constexpr</c-> <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>e</c-><c- p>)</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c->
    <c- n>operator</c-><c- p>()</c-> <c- p>(</c-><c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c-> <c- n>i</c-><c- p>,</c->
                <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c-> <c- n>j</c-><c- p>)</c-> <c- k>const</c-><c- p>;</c->

    <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
    <c- b>bool</c-> <c- n>operator</c-><c- o>==</c-><c- p>(</c-><c- k>const</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>m</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
    <c- b>bool</c-> <c- n>operator</c-><c- o>!=</c-><c- p>(</c-><c- k>const</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>m</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- n>constexpr</c-> <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c->
    <c- n>stride</c-><c- p>(</c-><c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c-> <c- n>r</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- n>constexpr</c-> <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c->
    <c- n>required_span_size</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- n>constexpr</c-> <c- n>Extents</c-> <c- n>extents</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_unique</c-><c- p>();</c->
    <c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_contiguous</c-><c- p>();</c->
    <c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_strided</c-><c- p>();</c->

    <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_unique</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
    <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_contiguous</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
    <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_strided</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
<c- p>};</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>Triangle</c-></code> is either <code class="highlight"><c- n>upper_triangle_t</c-></code> or <code class="highlight"><c- n>lower_triangle_t</c-></code>.</p>
      <li data-md>
       <p><code class="highlight"><c- n>StorageOrder</c-></code> is either <code class="highlight"><c- n>column_major_t</c-></code> or <code class="highlight"><c- n>row_major_t</c-></code>.</p>
      <li data-md>
       <p><code class="highlight"><c- n>Extents</c-></code> is a specialization of <code class="highlight"><c- n>extents</c-></code>.</p>
      <li data-md>
       <p><code class="highlight"><c- n>Extents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals 2.</p>
     </ul>
   </ul>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- nf>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>Extents</c-><c- o>&amp;</c-> <c- n>e</c-><c- p>);</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> <code class="highlight"><c- n>e</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>e</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Effects:</em> Initializes <code class="highlight"><c- n>extents_</c-></code> with <code class="highlight"><c- n>e</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
<c- n>constexpr</c-> <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>e</c-><c- p>);</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>OtherExtents</c-></code> is a specialization of <code class="highlight"><c- n>extents</c-></code>.</p>
      <li data-md>
       <p><code class="highlight"><c- n>OtherExtents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals 2.</p>
     </ul>
    <li data-md>
     <p><em>Effects:</em> Initializes <code class="highlight"><c- n>extents_</c-></code> with <code class="highlight"><c- n>e</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c->
<c- n>operator</c-><c- p>()</c-> <c- p>(</c-><c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c-> <c- n>i</c-><c- p>,</c->
            <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c-> <c- n>j</c-><c- p>)</c-> <c- k>const</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p>0 ≤ <code class="highlight"><c- n>i</c-></code> &lt; <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, and</p>
      <li data-md>
       <p>0 ≤ <code class="highlight"><c- n>j</c-></code> &lt; <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Returns:</em> Let <code class="highlight"><c- n>N</c-></code> equal <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.  Then:</p>
     <ul>
      <li data-md>
       <p>If <code class="highlight"><c- n>StorageOrder</c-></code> is <code class="highlight"><c- n>column_major_t</c-></code> and</p>
       <ul>
        <li data-md>
         <p>if <code class="highlight"><c- n>Triangle</c-></code> is <code class="highlight"><c- n>upper_triangle_t</c-></code>,
then <code class="highlight"><c- n>i</c-> <c- o>+</c-> <c- n>j</c-><c- p>(</c-><c- n>j</c-><c- o>+</c-><c- mi>1</c-><c- p>)</c-><c- o>/</c-><c- mi>2</c-></code> if <code class="highlight"><c- n>i</c-></code> >= <code class="highlight"><c- n>j</c-></code>,
else <code class="highlight"><c- n>j</c-> <c- o>+</c-> <c- n>i</c-><c- p>(</c-><c- n>i</c-><c- o>+</c-><c- mi>1</c-><c- p>)</c-><c- o>/</c-><c- mi>2</c-></code>;</p>
        <li data-md>
         <p>else, if <code class="highlight"><c- n>Triangle</c-></code> is <code class="highlight"><c- n>lower_triangle_t</c-></code>,
then <code class="highlight"><c- n>i</c-> <c- o>+</c-> <c- n>Nj</c-> <c- o>-</c-> <c- n>j</c-><c- p>(</c-><c- n>j</c-><c- o>+</c-><c- mi>1</c-><c- p>)</c-><c- o>/</c-><c- mi>2</c-></code> if <code class="highlight"><c- n>i</c-></code> &lt;= <code class="highlight"><c- n>j</c-></code>,
else <code class="highlight"><c- n>j</c-> <c- o>+</c-> <c- n>Ni</c-> <c- o>-</c-> <c- n>i</c-><c- p>(</c-><c- n>i</c-><c- o>+</c-><c- mi>1</c-><c- p>)</c-><c- o>/</c-><c- mi>2</c-></code>;</p>
       </ul>
      <li data-md>
       <p>else, if <code class="highlight"><c- n>StorageOrder</c-></code> is <code class="highlight"><c- n>row_major_t</c-></code> and</p>
       <ul>
        <li data-md>
         <p>if <code class="highlight"><c- n>Triangle</c-></code> is <code class="highlight"><c- n>upper_triangle_t</c-></code>,
then <code class="highlight"><c- n>j</c-> <c- o>+</c-> <c- n>Ni</c-> <c- o>-</c-> <c- n>i</c-><c- p>(</c-><c- n>i</c-><c- o>+</c-><c- mi>1</c-><c- p>)</c-><c- o>/</c-><c- mi>2</c-></code> if <code class="highlight"><c- n>j</c-></code> &lt;= <code class="highlight"><c- n>i</c-></code>,
else <code class="highlight"><c- n>i</c-> <c- o>+</c-> <c- n>Nj</c-> <c- o>-</c-> <c- n>j</c-><c- p>(</c-><c- n>j</c-><c- o>+</c-><c- mi>1</c-><c- p>)</c-><c- o>/</c-><c- mi>2</c-></code>;</p>
        <li data-md>
         <p>else, if <code class="highlight"><c- n>Triangle</c-></code> is <code class="highlight"><c- n>lower_triangle_t</c-></code>,
then <code class="highlight"><c- n>j</c-> <c- o>+</c-> <c- n>i</c-><c- p>(</c-><c- n>i</c-><c- o>+</c-><c- mi>1</c-><c- p>)</c-><c- o>/</c-><c- mi>2</c-></code> if <code class="highlight"><c- n>j</c-></code> >= <code class="highlight"><c- n>i</c-></code>,
else <code class="highlight"><c- n>i</c-> <c- o>+</c-> <c- n>j</c-><c- p>(</c-><c- n>j</c-><c- o>+</c-><c- mi>1</c-><c- p>)</c-><c- o>/</c-><c- mi>2</c-></code>.</p>
       </ul>
     </ul>
   </ul>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
<c- b>bool</c-> <c- n>operator</c-><c- o>==</c-><c- p>(</c-><c- k>const</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>m</c-><c- p>)</c-> <c- k>const</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Constraints:</em> <code class="highlight"><c- n>OtherExtents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals <code class="highlight"><c- n>rank</c-><c- p>()</c-></code>.</p>
    <li data-md>
     <p><em>Returns:</em> <code class="highlight">true</code> if and only if
for 0 ≤ <code class="highlight"><c- n>r</c-></code> &lt; <code class="highlight"><c- n>rank</c-><c- p>()</c-></code>, <code class="highlight"><c- n>m</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
<c- b>bool</c-> <c- n>operator</c-><c- o>!=</c-><c- p>(</c-><c- k>const</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>m</c-><c- p>)</c-> <c- k>const</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Constraints:</em> <code class="highlight"><c- n>OtherExtents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals <code class="highlight"><c- n>rank</c-><c- p>()</c-></code>.</p>
    <li data-md>
     <p><em>Returns:</em> <code class="highlight">true</code> if and only if
there exists <code class="highlight"><c- n>r</c-></code> with 0 ≤ <code class="highlight"><c- n>r</c-></code> &lt; <code class="highlight"><c- n>rank</c-><c- p>()</c-></code> such that <code class="highlight"><c- n>m</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> does not equal <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c->
<c- n>stride</c-><c- p>(</c-><c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c-> <c- n>r</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Returns:</em> 1 if <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> is less than 2, else 0.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c->
<c- n>required_span_size</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Returns:</em> <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-><c- o>*</c-><c- p>(</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-><c- o>/</c-><c- mi>2</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- n>Extents</c-> <c- n>extents</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- n>extents_</c-><c- p>;</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_unique</c-><c- p>();</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Returns:</em> <code class="highlight">false</code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_contiguous</c-><c- p>();</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Returns:</em> <code class="highlight">true</code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_strided</c-><c- p>();</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Returns:</em> <code class="highlight">false</code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_unique</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Returns:</em> <code class="highlight">true</code> if <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> is less than 2, else <code class="highlight">false</code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_contiguous</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Returns:</em> <code class="highlight">true</code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_strided</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Returns:</em> <code class="highlight">true</code> if <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> is less than 2, else <code class="highlight">false</code>.</p>
   </ul>
   <h3 class="heading settled" data-level="16.5" id="scaled-in-place-transformation-linalgscaled"><span class="secno">16.5. </span><span class="content">Scaled in-place transformation [linalg.scaled]</span><a class="self-link" href="#scaled-in-place-transformation-linalgscaled"></a></h3>
   <p>The <code class="highlight"><c- n>scaled</c-></code> function takes a value <code class="highlight"><c- n>alpha</c-></code> and an <code class="highlight"><c- n>mdspan</c-></code> <code class="highlight"><c- n>x</c-></code>, and returns a new read-only <code class="highlight"><c- n>mdspan</c-></code> with the same domain
as <code class="highlight"><c- n>x</c-></code>, that represents the elementwise product of <code class="highlight"><c- n>alpha</c-></code> with each
element of <code class="highlight"><c- n>x</c-></code>.</p>
   <p>[<em>Example:</em></p>
<pre class="language-c++ highlight"><c- c1>// z = alpha * x + y</c->
<c- b>void</c-> <c- nf>z_equals_alpha_times_x_plus_y</c-><c- p>(</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- n>dynamic_extent</c-><c- o>>></c-> <c- n>z</c-><c- p>,</c->
  <c- k>const</c-> <c- b>double</c-> <c- n>alpha</c-><c- p>,</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- n>dynamic_extent</c-><c- o>>></c-> <c- n>x</c-><c- p>,</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- n>dynamic_extent</c-><c- o>>></c-> <c- n>y</c-><c- p>)</c->
<c- p>{</c->
  <c- n>add</c-><c- p>(</c-><c- n>scaled</c-><c- p>(</c-><c- n>alpha</c-><c- p>,</c-> <c- n>x</c-><c- p>),</c-> <c- n>y</c-><c- p>,</c-> <c- n>y</c-><c- p>);</c->
<c- p>}</c->

<c- c1>// w = alpha * x + beta * y</c->
<c- b>void</c-> <c- nf>w_equals_alpha_times_x_plus_beta_times_y</c-><c- p>(</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- n>dynamic_extent</c-><c- o>>></c-> <c- n>w</c-><c- p>,</c->
  <c- k>const</c-> <c- b>double</c-> <c- n>alpha</c-><c- p>,</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- n>dynamic_extent</c-><c- o>>></c-> <c- n>x</c-><c- p>,</c->
  <c- k>const</c-> <c- b>double</c-> <c- n>beta</c-><c- p>,</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- n>dynamic_extent</c-><c- o>>></c-> <c- n>y</c-><c- p>)</c->
<c- p>{</c->
  <c- n>add</c-><c- p>(</c-><c- n>scaled</c-><c- p>(</c-><c- n>alpha</c-><c- p>,</c-> <c- n>x</c-><c- p>),</c-> <c- n>scaled</c-><c- p>(</c-><c- n>beta</c-><c- p>,</c-> <c- n>y</c-><c- p>),</c-> <c- n>w</c-><c- p>);</c->
<c- p>}</c->
</pre>
   --<em>end example</em>] 
   <p><em>[Note:</em></p>
   <p>An implementation could dispatch to a function in the BLAS library, by
noticing that the first argument has an <code class="highlight"><c- n>accessor_scaled</c-></code> <code class="highlight"><c- n>Accessor</c-></code> type.  It could use this information to extract the appropriate
run-time value(s) of the relevant BLAS function arguments (e.g., <code class="highlight"><c- n>ALPHA</c-></code> and/or <code class="highlight"><c- n>BETA</c-></code>), by calling <code class="highlight"><c- n>accessor_scaled</c-><c- o>::</c-><c- n>scaling_factor</c-></code>.</p>
   <p>--<em>end note]</em></p>
   <h4 class="heading settled" data-level="16.5.1" id="class-template-accessor_scaled-linalgscaledaccessor_scaled"><span class="secno">16.5.1. </span><span class="content">Class template <code class="highlight"><c- n>accessor_scaled</c-></code> [linalg.scaled.accessor_scaled]</span><a class="self-link" href="#class-template-accessor_scaled-linalgscaledaccessor_scaled"></a></h4>
   <p>The class template <code class="highlight"><c- n>accessor_scaled</c-></code> is an <code class="highlight"><c- n>mdspan</c-></code> accessor
policy whose reference type represents the product of a fixed value
(the "scaling factor") and its nested <code class="highlight"><c- n>mdspan</c-></code> accessor’s
reference.  It is part of the implementation of <code class="highlight"><c- n>scaled</c-></code>.</p>
   <p>The exposition-only class template <code class="highlight"><c- n>scaled_scalar</c-></code> represents a
read-only value, which is the product of a fixed value (the "scaling
factor") and the value of a reference to an element of a <code class="highlight"><c- n>mdspan</c-></code>. <em>[Note:</em> The value is read only to avoid confusion
with the definition of "assigning to a scaled scalar."  --<em>end note]</em> <code class="highlight"><c- n>scaled_scalar</c-></code> is part of the implementation of <code class="highlight"><c- n>scaled_accessor</c-></code>.</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ScalingFactor</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Reference</c-><c- o>></c->
<c- n>class</c-> <c- n>scaled_scalar</c-> <c- p>{</c-> <c- c1>// exposition only</c->
<c- nl>private</c-><c- p>:</c->
  <c- k>const</c-> <c- n>ScalingFactor</c-> <c- n>scaling_factor</c-><c- p>;</c->
  <c- n>Reference</c-> <c- n>value</c-><c- p>;</c->
  <c- n>using</c-> <c- n>result_type</c-> <c- o>=</c->
    <c- n>decltype</c-> <c- p>(</c-><c- n>scaling_factor</c-> <c- o>*</c-> <c- n>value</c-><c- p>);</c->

<c- nl>public</c-><c- p>:</c->
  <c- n>scaled_scalar</c-><c- p>(</c-><c- k>const</c-> <c- n>ScalingFactor</c-><c- o>&amp;</c-> <c- n>s</c-><c- p>,</c-> <c- n>Reference</c-> <c- n>v</c-><c- p>);</c->

  <c- n>operator</c-> <c- nf>result_type</c-><c- p>()</c-> <c- k>const</c-><c- p>;</c->
<c- p>};</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> <code class="highlight"><c- n>ScalingFactor</c-></code> and <code class="highlight"><c- n>Reference</c-></code> shall be <em>Cpp17CopyConstructible</em>.</p>
    <li data-md>
     <p><em>Constraints:</em> The expression <code class="highlight"><c- n>scaling_factor</c-> <c- o>*</c-> <c- n>value</c-></code> is well formed.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>scaled_scalar</c-><c- p>(</c-><c- k>const</c-> <c- n>ScalingFactor</c-><c- o>&amp;</c-> <c- n>s</c-><c- p>,</c-> <c- n>Reference</c-> <c- n>v</c-><c- p>);</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Initializes <code class="highlight"><c- n>scaling_factor</c-></code> with <code class="highlight"><c- n>s</c-></code>, and initializes <code class="highlight"><c- n>value</c-></code> with <code class="highlight"><c- n>v</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>operator</c-> <c- nf>result_type</c-><c- p>()</c-> <c- k>const</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> This operator may be invoked arbitrarily many times.</p>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- n>scaling_factor</c-> <c- o>*</c-> <c- n>value</c-><c- p>;</c-></code>.</p>
   </ul>
   <p>The class template <code class="highlight"><c- n>accessor_scaled</c-></code> is an <code class="highlight"><c- n>mdspan</c-></code> accessor
policy whose reference type represents the product of a scaling factor
and its nested <code class="highlight"><c- n>mdspan</c-></code> accessor’s reference.</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ScalingFactor</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Accessor</c-><c- o>></c->
<c- n>class</c-> <c- n>accessor_scaled</c-> <c- p>{</c->
<c- nl>public</c-><c- p>:</c->
  <c- n>using</c-> <c- n>element_type</c->  <c- o>=</c-> <c- n>Accessor</c-><c- o>::</c-><c- n>element_type</c-><c- p>;</c->
  <c- n>using</c-> <c- n>pointer</c->       <c- o>=</c-> <c- n>Accessor</c-><c- o>::</c-><c- n>pointer</c-><c- p>;</c->
  <c- n>using</c-> <c- n>reference</c->     <c- o>=</c->
    <c- n>scaled_scalar</c-><c- o>&lt;</c-><c- n>ScalingFactor</c-><c- p>,</c-> <c- n>Accessor</c-><c- o>::</c-><c- n>reference</c-><c- o>></c-><c- p>;</c->
  <c- n>using</c-> <c- n>offset_policy</c-> <c- o>=</c->
    <c- n>accessor_scaled</c-><c- o>&lt;</c-><c- n>ScalingFactor</c-><c- p>,</c-> <c- n>Accessor</c-><c- o>::</c-><c- n>offset_policy</c-><c- o>></c-><c- p>;</c->

  <c- n>accessor_scaled</c-><c- p>(</c-><c- k>const</c-> <c- n>ScalingFactor</c-><c- o>&amp;</c-> <c- n>s</c-><c- p>,</c-> <c- n>Accessor</c-> <c- n>a</c-><c- p>);</c->

  <c- n>reference</c-> <c- nf>access</c-><c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>i</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

  <c- n>offset_policy</c-><c- o>::</c-><c- n>pointer</c->
  <c- n>offset</c-><c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>i</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

  <c- n>element_type</c-><c- o>*</c-> <c- nf>decay</c-><c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

  <c- n>ScalingFactor</c-> <c- nf>scaling_factor</c-><c- p>()</c-> <c- k>const</c-><c- p>;</c->

<c- nl>private</c-><c- p>:</c->
  <c- k>const</c-> <c- n>ScalingFactor</c-> <c- n>scaling_factor_</c-><c- p>;</c-> <c- c1>// exposition only</c->
  <c- n>Accessor</c-> <c- n>accessor</c-><c- p>;</c-> <c- c1>// exposition only</c->
<c- p>};</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>ScalingFactor</c-></code> and <code class="highlight"><c- n>Accessor</c-></code> shall be <em>Cpp17CopyConstructible</em>.</p>
      <li data-md>
       <p><code class="highlight"><c- n>Accessor</c-></code> shall meet the <code class="highlight"><c- n>mdspan</c-></code> accessor policy requirements.</p>
     </ul>
   </ul>
<pre class="language-c++ highlight"><c- n>accessor_scaled</c-><c- p>(</c-><c- k>const</c-> <c- n>ScalingFactor</c-><c- o>&amp;</c-> <c- n>s</c-><c- p>,</c-> <c- n>Accessor</c-> <c- n>a</c-><c- p>);</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Initializes <code class="highlight"><c- n>scaling_factor_</c-></code> with <code class="highlight"><c- n>s</c-></code>, and initializes <code class="highlight"><c- n>accessor</c-></code> with <code class="highlight"><c- n>a</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>reference</c-> <c- nf>access</c-><c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>i</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- nf>reference</c-><c- p>(</c-><c- n>scaling_factor_</c-><c- p>,</c-> <c- n>accessor</c-><c- p>.</c-><c- n>access</c-><c- p>(</c-><c- n>p</c-><c- p>,</c-> <c- n>i</c-><c- p>));</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>offset_policy</c-><c- o>::</c-><c- n>pointer</c->
<c- n>offset</c-><c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>i</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- n>accessor</c-><c- p>.</c-><c- n>offset</c-><c- p>(</c-><c- n>p</c-><c- p>,</c-> <c- n>i</c-><c- p>);</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>element_type</c-><c- o>*</c-> <c- nf>decay</c-><c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- n>accessor</c-><c- p>.</c-><c- n>decay</c-><c- p>(</c-><c- n>p</c-><c- p>);</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>ScalingFactor</c-> <c- nf>scaling_factor</c-><c- p>()</c-> <c- k>const</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- n>scaling_factor_</c-><c- p>;</c-></code>.</p>
   </ul>
   <h4 class="heading settled" data-level="16.5.2" id="scaled-linalgscaledscaled"><span class="secno">16.5.2. </span><span class="content"><code class="highlight"><c- n>scaled</c-></code> [linalg.scaled.scaled]</span><a class="self-link" href="#scaled-linalgscaledscaled"></a></h4>
   <p>The <code class="highlight"><c- n>scaled</c-></code> function takes a value <code class="highlight"><c- n>alpha</c-></code> and an <code class="highlight"><c- n>mdspan</c-></code> <code class="highlight"><c- n>x</c-></code>, and returns a new read-only <code class="highlight"><c- n>mdspan</c-></code> with the same domain
as <code class="highlight"><c- n>x</c-></code>, that represents the elementwise product of <code class="highlight"><c- n>alpha</c-></code> with each
element of <code class="highlight"><c- n>x</c-></code>.</p>
   <p>For <code class="highlight"><c- n>i</c-><c- p>...</c-></code> in the domain of <code class="highlight"><c- n>x</c-></code>,
the mathematical expression for element <code class="highlight"><c- n>i</c-><c- p>...</c-></code> of <code class="highlight"><c- n>scaled</c-><c- p>(</c-><c- n>alpha</c-><c- p>,</c-> <c- n>x</c-><c- p>)</c-></code> is <code class="highlight"><c- n>alpha</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>...]</c-></code>. <em>[Note:</em> Terms in this product will not be reordered.
--<em>end note]</em></p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ScalingFactor</c-><c- p>,</c->
         <c- n>class</c-> <c- n>ElementType</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Extents</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Layout</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Accessor</c-><c- o>></c->
<c- d>/* see below */</c->
<c- n>scaled</c-><c- p>(</c->
  <c- k>const</c-> <c- n>ScalingFactor</c-><c- o>&amp;</c-> <c- n>alpha</c-><c- p>,</c->
  <c- k>const</c-> <c- n>mdspan</c-><c- o>&lt;</c-><c- n>ElementType</c-><c- p>,</c-> <c- n>Extents</c-><c- p>,</c-> <c- n>Layout</c-><c- p>,</c-> <c- n>Accessor</c-><c- o>>&amp;</c-> <c- n>x</c-><c- p>);</c->
</pre>
   <p>Let <code class="highlight"><c- n>R</c-></code> name the type <code class="highlight"><c- n>mdspan</c-><c- o>&lt;</c-><c- n>ReturnElementType</c-><c- p>,</c-> <c- n>Extents</c-><c- p>,</c-> <c- n>Layout</c-><c- p>,</c-> <c- n>ReturnAccessor</c-><c- o>></c-></code>,
where</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>ReturnElementType</c-></code> is either <code class="highlight"><c- n>ElementType</c-></code> or <code class="highlight"><c- k>const</c-> <c- n>ElementType</c-></code>; and</p>
    <li data-md>
     <p><code class="highlight"><c- n>ReturnAccessor</c-></code> is:</p>
     <ul>
      <li data-md>
       <p>if <code class="highlight"><c- n>Accessor</c-></code> is <code class="highlight"><c- n>accessor_scaled</c-><c- o>&lt;</c-><c- n>NestedScalingFactor</c-><c- p>,</c-> <c- n>NestedAccessor</c-><c- o>></c-></code> for some <code class="highlight"><c- n>NestedScalingFactor</c-></code> and <code class="highlight"><c- n>NestedAccessor</c-></code>, then
either <code class="highlight"><c- n>accessor_scaled</c-><c- o>&lt;</c-><c- n>ProductScalingFactor</c-><c- p>,</c-> <c- n>NestedAccessor</c-><c- o>></c-></code> or <code class="highlight"><c- n>accessor_scaled</c-><c- o>&lt;</c-><c- n>ScalingFactor</c-><c- p>,</c-> <c- n>Accessor</c-><c- o>></c-></code>,
where <code class="highlight"><c- n>ProductScalingFactor</c-></code> is <code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>alpha</c-> <c- o>*</c-> <c- n>x</c-><c- p>.</c-><c- n>accessor</c-><c- p>().</c-><c- n>scaling_factor</c-><c- p>())</c-></code>;</p>
      <li data-md>
       <p>else, <code class="highlight"><c- n>accessor_scaled</c-><c- o>&lt;</c-><c- n>ScalingFactor</c-><c- p>,</c-> <c- n>Accessor</c-><c- o>></c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Effects:</em></p>
     <ul>
      <li data-md>
       <p>If <code class="highlight"><c- n>Accessor</c-></code> is <code class="highlight"><c- n>accessor_scaled</c-><c- o>&lt;</c-><c- n>NestedScalingFactor</c-><c- p>,</c-> <c- n>NestedAccessor</c-><c- o>></c-></code> and <code class="highlight"><c- n>ReturnAccessor</c-></code> is <code class="highlight"><c- n>accessor_scaled</c-><c- o>&lt;</c-><c- n>ProductScalingFactor</c-><c- p>,</c-> <c- n>NestedAccessor</c-><c- o>></c-></code>,
then equivalent to <code class="highlight"><c- k>return</c-> <c- nf>R</c-><c- p>(</c-><c- n>x</c-><c- p>.</c-><c- n>data</c-><c- p>(),</c-> <c- n>x</c-><c- p>.</c-><c- n>mapping</c-><c- p>(),</c-> <c- n>ReturnAccessor</c-><c- p>(</c-><c- n>product_alpha</c-><c- p>,</c-> <c- n>x</c-><c- p>.</c-><c- n>accessor</c-><c- p>().</c-><c- n>nested_accessor</c-><c- p>()));</c-></code>,
where <code class="highlight"><c- n>product_alpha</c-></code> equals <code class="highlight"><c- n>alpha</c-> <c- o>*</c-> <c- n>x</c-><c- p>.</c-><c- n>accessor</c-><c- p>().</c-><c- n>scaling_factor</c-><c- p>()</c-></code>;</p>
      <li data-md>
       <p>else, equivalent to <code class="highlight"><c- k>return</c-> <c- nf>R</c-><c- p>(</c-><c- n>x</c-><c- p>.</c-><c- n>data</c-><c- p>(),</c-> <c- n>x</c-><c- p>.</c-><c- n>mapping</c-><c- p>(),</c-> <c- n>ReturnAccessor</c-><c- p>(</c-><c- n>alpha</c-><c- p>,</c-> <c- n>x</c-><c- p>.</c-><c- n>accessor</c-><c- p>()));</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Remarks:</em> The elements of the returned <code class="highlight"><c- n>mdspan</c-></code> are read only.</p>
   </ul>
   <p><em>[Note:</em></p>
   <p>The point of <code class="highlight"><c- n>ReturnAccessor</c-></code> is to give implementations freedom
to optimize applying <code class="highlight"><c- n>accessor_scaled</c-></code> twice in a row.
However, implementations are not required to optimize arbitrary combinations
of nested <code class="highlight"><c- n>accessor_scaled</c-></code> interspersed with other nested accessors.</p>
   <p>The point of <code class="highlight"><c- n>ReturnElementType</c-></code> is that <code class="highlight"><c- n>mdspan</c-></code> does not provide a generic mechanism
for deducing the const version of <code class="highlight"><c- n>Accessor</c-></code> for use in <code class="highlight"><c- n>accessor_scaled</c-></code>.
In general, it may not be correct or efficient to use an <code class="highlight"><c- n>Accessor</c-></code> meant for a nonconst <code class="highlight"><c- n>ElementType</c-></code>, with <code class="highlight"><c- k>const</c-> <c- n>ElementType</c-></code>.
This is because <code class="highlight"><c- n>Accessor</c-><c- o>::</c-><c- n>reference</c-></code> may be a type other than <code class="highlight"><c- n>ElementType</c-><c- o>&amp;</c-></code>.
Thus, we cannot require that the return type have <code class="highlight"><c- k>const</c-> <c- n>ElementType</c-></code> as its element type,
since that might not be compatible with the given <code class="highlight"><c- n>Accessor</c-></code>.
However, in some cases, like <code class="highlight"><c- n>default_accessor</c-></code>,
it is possible to deduce the const version of <code class="highlight"><c- n>Accessor</c-></code>.
Regardless, users are not allowed to modify the elements of the returned <code class="highlight"><c- n>mdspan</c-></code>.</p>
   <p>--<em>end note]</em></p>
   <p>[<em>Example:</em></p>
<pre class="language-c++ highlight"><c- b>void</c-> <c- nf>test_scaled</c-><c- p>(</c-><c- n>mdspan</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- mi>10</c-><c- o>>></c-> <c- n>x</c-><c- p>)</c->
<c- p>{</c->
  <c- k>auto</c-> <c- n>x_scaled</c-> <c- o>=</c-> <c- n>scaled</c-><c- p>(</c-><c- mf>5.0</c-><c- p>,</c-> <c- n>x</c-><c- p>);</c->
  <c- k>for</c-><c- p>(</c-><c- b>int</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>&lt;</c-> <c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>);</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c-> <c- p>{</c->
    <c- n>assert</c-><c- p>(</c-><c- n>x_scaled</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>==</c-> <c- mf>5.0</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]);</c->
  <c- p>}</c->
<c- p>}</c->
</pre>
   --<em>end example</em>] 
   <h3 class="heading settled" data-level="16.6" id="conjugated-in-place-transformation-linalgconj"><span class="secno">16.6. </span><span class="content">Conjugated in-place transformation [linalg.conj]</span><a class="self-link" href="#conjugated-in-place-transformation-linalgconj"></a></h3>
   <p>The <code class="highlight"><c- n>conjugated</c-></code> function takes an <code class="highlight"><c- n>mdspan</c-></code> <code class="highlight"><c- n>x</c-></code>, and returns
a new read-only <code class="highlight"><c- n>mdspan</c-></code> <code class="highlight"><c- n>y</c-></code> with the same domain as <code class="highlight"><c- n>x</c-></code>, whose
elements are the complex conjugates of the corresponding elements of <code class="highlight"><c- n>x</c-></code>.  If the element type of <code class="highlight"><c- n>x</c-></code> is not <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- n>R</c-><c- o>></c-></code> for some <code class="highlight"><c- n>R</c-></code>,
then <code class="highlight"><c- n>y</c-></code> is a read-only view of the elements of <code class="highlight"><c- n>x</c-></code>.</p>
   <p><em>[Note:</em></p>
   <p>An implementation could dispatch to a function in the BLAS library, by
noticing that the <code class="highlight"><c- n>Accessor</c-></code> type of an <code class="highlight"><c- n>mdspan</c-></code> input has type <code class="highlight"><c- n>accessor_conjugate</c-></code>, and that its nested <code class="highlight"><c- n>Accessor</c-></code> type is
compatible with the BLAS library.  If so, it could set the
corresponding <code class="highlight"><c- n>TRANS</c-><c- o>*</c-></code> BLAS function argument accordingly and call the
BLAS function.</p>
   <p>--<em>end note]</em></p>
   <h4 class="heading settled" data-level="16.6.1" id="class-template-accessor_conjugate-linalgconjaccessor_conjugate"><span class="secno">16.6.1. </span><span class="content">Class template <code class="highlight"><c- n>accessor_conjugate</c-></code> [linalg.conj.accessor_conjugate]</span><a class="self-link" href="#class-template-accessor_conjugate-linalgconjaccessor_conjugate"></a></h4>
   <p>The class template <code class="highlight"><c- n>accessor_conjugate</c-></code> is an <code class="highlight"><c- n>mdspan</c-></code> accessor
policy whose reference type represents the complex conjugate of its
nested <code class="highlight"><c- n>mdspan</c-></code> accessor’s reference.</p>
   <p>The exposition-only class template <code class="highlight"><c- n>conjugated_scalar</c-></code> represents a
read-only value, which is the complex conjugate of the value of a
reference to an element of an <code class="highlight"><c- n>mdspan</c-></code>. <em>[Note:</em> The value is
read only to avoid confusion with the definition of "assigning to the
conjugate of a scalar."  --<em>end note]</em> <code class="highlight"><c- n>conjugated_scalar</c-></code> is part of
the implementation of <code class="highlight"><c- n>accessor_conjugate</c-></code>.</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Reference</c-><c- p>,</c->
         <c- n>class</c-> <c- n>ElementType</c-><c- o>></c->
<c- n>class</c-> <c- n>conjugated_scalar</c-> <c- p>{</c-> <c- c1>// exposition only</c->
<c- nl>public</c-><c- p>:</c->
  <c- n>conjugated_scalar</c-><c- p>(</c-><c- n>Reference</c-> <c- n>v</c-><c- p>);</c->

  <c- n>operator</c-> <c- nf>ElementType</c-><c- p>()</c-> <c- k>const</c-><c- p>;</c->

  <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>T2</c-><c- o>></c->
  <c- k>auto</c-> <c- n>operator</c-><c- o>*</c-> <c- p>(</c-><c- k>const</c-> <c- n>T2</c-> <c- n>upd</c-><c- p>)</c-> <c- k>const</c-> <c- p>{</c->
    <c- n>using</c-> <c- n>std</c-><c- o>::</c-><c- n>conj</c-><c- p>;</c->
    <c- k>return</c-> <c- nf>conj</c-><c- p>(</c-><c- n>val</c-><c- p>)</c-> <c- o>*</c-> <c- n>upd</c-><c- p>;</c->
  <c- p>}</c->

  <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>T2</c-><c- o>></c->
  <c- k>auto</c-> <c- n>operator</c-><c- o>+</c-> <c- p>(</c-><c- k>const</c-> <c- n>T2</c-> <c- n>upd</c-><c- p>)</c-> <c- k>const</c-> <c- p>{</c->
    <c- n>using</c-> <c- n>std</c-><c- o>::</c-><c- n>conj</c-><c- p>;</c->
    <c- k>return</c-> <c- nf>conj</c-><c- p>(</c-><c- n>val</c-><c- p>)</c-> <c- o>+</c-> <c- n>upd</c-><c- p>;</c->
  <c- p>}</c->

  <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>T2</c-><c- o>></c->
  <c- b>bool</c-> <c- n>operator</c-><c- o>==</c-> <c- p>(</c-><c- k>const</c-> <c- n>T2</c-> <c- n>upd</c-><c- p>)</c-> <c- k>const</c-> <c- p>{</c->
    <c- n>using</c-> <c- n>std</c-><c- o>::</c-><c- n>conj</c-><c- p>;</c->
    <c- k>return</c-> <c- nf>conj</c-><c- p>(</c-><c- n>val</c-><c- p>)</c-> <c- o>==</c-> <c- n>upd</c-><c- p>;</c->
  <c- p>}</c->

  <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>T2</c-><c- o>></c->
  <c- b>bool</c-> <c- n>operator</c-><c- o>!=</c-> <c- p>(</c-><c- k>const</c-> <c- n>T2</c-> <c- n>upd</c-><c- p>)</c-> <c- k>const</c-> <c- p>{</c->
    <c- n>using</c-> <c- n>std</c-><c- o>::</c-><c- n>conj</c-><c- p>;</c->
    <c- k>return</c-> <c- nf>conj</c-><c- p>(</c-><c- n>val</c-><c- p>)</c-> <c- o>!=</c-> <c- n>upd</c-><c- p>;</c->
  <c- p>}</c->

<c- nl>private</c-><c- p>:</c->
  <c- n>Reference</c-> <c- n>val</c-><c- p>;</c->
<c- p>};</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>T1</c-><c- p>,</c-> <c- n>class</c-> <c- n>Reference</c-><c- p>,</c-> <c- n>class</c-> <c- n>Element</c-><c- o>></c->
<c- k>auto</c-> <c- n>operator</c-><c- o>*</c-> <c- p>(</c-><c- k>const</c-> <c- n>T1</c-> <c- n>x</c-><c- p>,</c-> <c- k>const</c-> <c- n>conjugated_scalar</c-><c- o>&lt;</c-><c- n>Reference</c-><c- p>,</c-> <c- n>Element</c-><c- o>></c-> <c- n>y</c-><c- p>)</c-> <c- p>{</c->
  <c- k>return</c-> <c- n>x</c-> <c- o>*</c-> <c- n>Reference</c-><c- p>(</c-><c- n>y</c-><c- p>);</c->
<c- p>}</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> <code class="highlight"><c- n>Reference</c-></code> shall be <em>Cpp17CopyConstructible</em>.</p>
    <li data-md>
     <p><em>Constraints:</em> The expression <code class="highlight"><c- n>conj</c-><c- p>(</c-><c- n>val</c-><c- p>)</c-></code> is well formed and is convertible to <code class="highlight"><c- n>ElementType</c-></code>. <em>[Note:</em> This implies that <code class="highlight"><c- n>ElementType</c-></code> is <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- n>R</c-><c- o>></c-></code> for some type <code class="highlight"><c- n>R</c-></code>.  --<em>end note]</em></p>
   </ul>
<pre class="language-c++ highlight"><c- n>conjugated_scalar</c-><c- p>(</c-><c- n>Reference</c-> <c- n>v</c-><c- p>);</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Initializes <code class="highlight"><c- n>val</c-></code> with <code class="highlight"><c- n>v</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>operator</c-> <c- nf>T</c-><c- p>()</c-> <c- k>const</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- nf>conj</c-><c- p>(</c-><c- n>val</c-><c- p>);</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Accessor</c-><c- o>></c->
<c- n>class</c-> <c- n>accessor_conjugate</c-> <c- p>{</c->
<c- nl>private</c-><c- p>:</c->
  <c- n>Accessor</c-> <c- n>acc</c-><c- p>;</c-> <c- c1>// exposition only</c->

<c- nl>public</c-><c- p>:</c->
  <c- n>using</c-> <c- n>element_type</c->  <c- o>=</c-> <c- n>typename</c-> <c- n>Accessor</c-><c- o>::</c-><c- n>element_type</c-><c- p>;</c->
  <c- n>using</c-> <c- n>pointer</c->       <c- o>=</c-> <c- n>typename</c-> <c- n>Accessor</c-><c- o>::</c-><c- n>pointer</c-><c- p>;</c->
  <c- n>using</c-> <c- n>reference</c->     <c- o>=</c-> <c- d>/* see below */</c-><c- p>;</c->
  <c- n>using</c-> <c- n>offset_policy</c-> <c- o>=</c-> <c- d>/* see below */</c-><c- p>;</c->

  <c- n>accessor_conjugate</c-><c- p>(</c-><c- n>Accessor</c-> <c- n>a</c-><c- p>);</c->

  <c- n>reference</c-> <c- nf>access</c-><c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>i</c-><c- p>)</c-> <c- k>const</c->
    <c- n>noexcept</c-><c- p>(</c-><c- n>noexcept</c-><c- p>(</c-><c- n>reference</c-><c- p>(</c-><c- n>acc</c-><c- p>.</c-><c- n>access</c-><c- p>(</c-><c- n>p</c-><c- p>,</c-> <c- n>i</c-><c- p>))));</c->

  <c- n>typename</c-> <c- n>offset_policy</c-><c- o>::</c-><c- n>pointer</c->
  <c- n>offset</c-><c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>i</c-><c- p>)</c-> <c- k>const</c->
    <c- n>noexcept</c-><c- p>(</c-><c- n>noexcept</c-><c- p>(</c-><c- n>acc</c-><c- p>.</c-><c- n>offset</c-><c- p>(</c-><c- n>p</c-><c- p>,</c-> <c- n>i</c-><c- p>)));</c->

  <c- n>element_type</c-><c- o>*</c-> <c- nf>decay</c-><c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>)</c-> <c- k>const</c->
    <c- n>noexcept</c-><c- p>(</c-><c- n>noexcept</c-><c- p>(</c-><c- n>acc</c-><c- p>.</c-><c- n>decay</c-><c- p>(</c-><c- n>p</c-><c- p>)));</c->

  <c- n>Accessor</c-> <c- nf>nested_accessor</c-><c- p>()</c-> <c- k>const</c-><c- p>;</c->
<c- p>};</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>Accessor</c-></code> shall be <em>Cpp17CopyConstructible</em>.</p>
      <li data-md>
       <p><code class="highlight"><c- n>Accessor</c-></code> shall meet the <code class="highlight"><c- n>mdspan</c-></code> accessor policy requirements.</p>
     </ul>
   </ul>
<pre class="language-c++ highlight"><c- n>using</c-> <c- n>reference</c-> <c- o>=</c-> <c- d>/* see below */</c-><c- p>;</c->
</pre>
   <p>If <code class="highlight"><c- n>element_type</c-></code> is <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- n>R</c-><c- o>></c-></code> for some <code class="highlight"><c- n>R</c-></code>, then this names <code class="highlight"><c- n>conjugated_scalar</c-><c- o>&lt;</c-><c- k>typename</c-> <c- nc>Accessor</c-><c- o>::</c-><c- n>reference</c-><c- p>,</c-> <c- n>element_type</c-><c- o>></c-></code>.
Otherwise, it names <code class="highlight"><c- k>typename</c-> <c- nc>Accessor</c-><c- o>::</c-><c- n>reference</c-></code>.</p>
<pre class="language-c++ highlight"><c- n>using</c-> <c- n>offset_policy</c-> <c- o>=</c-> <c- d>/* see below */</c-><c- p>;</c->
</pre>
   <p>If <code class="highlight"><c- n>element_type</c-></code> is <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- n>R</c-><c- o>></c-></code> for some <code class="highlight"><c- n>R</c-></code>, then this names <code class="highlight"><c- n>accessor_conjugate</c-><c- o>&lt;</c-><c- k>typename</c-> <c- nc>Accessor</c-><c- o>::</c-><c- n>offset_policy</c-><c- p>,</c-> <c- n>element_type</c-><c- o>></c-></code>.
Otherwise, it names <code class="highlight"><c- k>typename</c-> <c- nc>Accessor</c-><c- o>::</c-><c- n>offset_policy</c-><c- o>></c-></code>.</p>
<pre class="language-c++ highlight"><c- n>accessor_conjugate</c-><c- p>(</c-><c- n>Accessor</c-> <c- n>a</c-><c- p>);</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Initializes <code class="highlight"><c- n>acc</c-></code> with <code class="highlight"><c- n>a</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>reference</c-> <c- nf>access</c-><c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>i</c-><c- p>)</c-> <c- k>const</c->
  <c- n>noexcept</c-><c- p>(</c-><c- n>noexcept</c-><c- p>(</c-><c- n>reference</c-><c- p>(</c-><c- n>acc</c-><c- p>.</c-><c- n>access</c-><c- p>(</c-><c- n>p</c-><c- p>,</c-> <c- n>i</c-><c- p>))));</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- nf>reference</c-><c- p>(</c-><c- n>acc</c-><c- p>.</c-><c- n>access</c-><c- p>(</c-><c- n>p</c-><c- p>,</c-> <c- n>i</c-><c- p>));</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>typename</c-> <c- n>offset_policy</c-><c- o>::</c-><c- n>pointer</c->
<c- n>offset</c-><c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>i</c-><c- p>)</c-> <c- k>const</c->
  <c- n>noexcept</c-><c- p>(</c-><c- n>noexcept</c-><c- p>(</c-><c- n>acc</c-><c- p>.</c-><c- n>offset</c-><c- p>(</c-><c- n>p</c-><c- p>,</c-> <c- n>i</c-><c- p>)));</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- n>acc</c-><c- p>.</c-><c- n>offset</c-><c- p>(</c-><c- n>p</c-><c- p>,</c-> <c- n>i</c-><c- p>);</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>element_type</c-><c- o>*</c-> <c- nf>decay</c-><c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>)</c-> <c- k>const</c->
  <c- n>noexcept</c-><c- p>(</c-><c- n>noexcept</c-><c- p>(</c-><c- n>acc</c-><c- p>.</c-><c- n>decay</c-><c- p>(</c-><c- n>p</c-><c- p>)));</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- n>acc</c-><c- p>.</c-><c- n>decay</c-><c- p>(</c-><c- n>p</c-><c- p>);</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>Accessor</c-> <c- nf>nested_accessor</c-><c- p>()</c-> <c- k>const</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- n>acc</c-><c- p>;</c-></code>.</p>
   </ul>
   <h4 class="heading settled" data-level="16.6.2" id="conjugated-linalgconjconjugated"><span class="secno">16.6.2. </span><span class="content"><code class="highlight"><c- n>conjugated</c-></code> [linalg.conj.conjugated]</span><a class="self-link" href="#conjugated-linalgconjconjugated"></a></h4>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ElementType</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Extents</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Layout</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Accessor</c-><c- o>></c->
<c- d>/* see-below */</c->
<c- n>conjugated</c-><c- p>(</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- n>ElementType</c-><c- p>,</c-> <c- n>Extents</c-><c- p>,</c-> <c- n>Layout</c-><c- p>,</c-> <c- n>Accessor</c-><c- o>></c-> <c- n>a</c-><c- p>);</c->
</pre>
   <p>Let <code class="highlight"><c- n>R</c-></code> name the type <code class="highlight"><c- n>mdspan</c-><c- o>&lt;</c-><c- n>ReturnElementType</c-><c- p>,</c-> <c- n>Extents</c-><c- p>,</c-> <c- n>Layout</c-><c- p>,</c-> <c- n>ReturnAccessor</c-><c- o>></c-></code>,
where</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>ReturnElementType</c-></code> is either <code class="highlight"><c- n>ElementType</c-></code> or <code class="highlight"><c- k>const</c-> <c- n>ElementType</c-></code>; and</p>
    <li data-md>
     <p><code class="highlight"><c- n>ReturnAccessor</c-></code> is:</p>
     <ul>
      <li data-md>
       <p>if <code class="highlight"><c- n>Accessor</c-></code> is <code class="highlight"><c- n>accessor_conjugate</c-><c- o>&lt;</c-><c- n>NestedAccessor</c-><c- o>></c-></code> for some <code class="highlight"><c- n>NestedAccessor</c-></code>, then
either <code class="highlight"><c- n>NestedAccessor</c-></code> or <code class="highlight"><c- n>accessor_conjugate</c-><c- o>&lt;</c-><c- n>Accessor</c-><c- o>></c-></code>,</p>
      <li data-md>
       <p>else if <code class="highlight"><c- n>ElementType</c-></code> is <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- n>U</c-><c- o>></c-></code> or <code class="highlight"><c- k>const</c-> <c- n>complex</c-><c- o>&lt;</c-><c- n>U</c-><c- o>></c-></code> for
some <code class="highlight"><c- n>U</c-></code>, then <code class="highlight"><c- n>accessor_conjugate</c-><c- o>&lt;</c-><c- n>Accessor</c-><c- o>></c-></code>,</p>
      <li data-md>
       <p>else either <code class="highlight"><c- n>accessor_conjugate</c-><c- o>&lt;</c-><c- n>Accessor</c-><c- o>></c-></code> or <code class="highlight"><c- n>Accessor</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Effects:</em></p>
     <ul>
      <li data-md>
       <p>If <code class="highlight"><c- n>Accessor</c-></code> is <code class="highlight"><c- n>accessor_conjugate</c-><c- o>&lt;</c-><c- n>NestedAccessor</c-><c- o>></c-></code> and <code class="highlight"><c- n>ReturnAccessor</c-></code> is <code class="highlight"><c- n>NestedAccessor</c-></code>, then equivalent to <code class="highlight"><c- k>return</c-> <c- nf>R</c-><c- p>(</c-><c- n>a</c-><c- p>.</c-><c- n>data</c-><c- p>(),</c-> <c- n>a</c-><c- p>.</c-><c- n>mapping</c-><c- p>(),</c-> <c- n>a</c-><c- p>.</c-><c- n>nested_accessor</c-><c- p>());</c-></code>;</p>
      <li data-md>
       <p>else, if <code class="highlight"><c- n>ReturnAccessor</c-></code> is <code class="highlight"><c- n>accessor_conjugate</c-><c- o>&lt;</c-><c- n>Accessor</c-><c- o>></c-></code>, then
equivalent to <code class="highlight"><c- k>return</c-> <c- nf>R</c-><c- p>(</c-><c- n>a</c-><c- p>.</c-><c- n>data</c-><c- p>(),</c-> <c- n>a</c-><c- p>.</c-><c- n>mapping</c-><c- p>(),</c-> <c- n>accessor_conjugate</c-><c- o>&lt;</c-><c- n>Accessor</c-><c- o>></c-><c- p>(</c-><c- n>a</c-><c- p>.</c-><c- n>accessor</c-><c- p>()));</c-></code>;</p>
      <li data-md>
       <p>else, equivalent to <code class="highlight"><c- k>return</c-> <c- nf>R</c-><c- p>(</c-><c- n>a</c-><c- p>.</c-><c- n>data</c-><c- p>(),</c-> <c- n>a</c-><c- p>.</c-><c- n>mapping</c-><c- p>(),</c-> <c- n>a</c-><c- p>.</c-><c- n>accessor</c-><c- p>());</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Remarks:</em> The elements of the returned <code class="highlight"><c- n>mdspan</c-></code> are read only.</p>
   </ul>
   <p><em>[Note:</em></p>
   <p>The point of <code class="highlight"><c- n>ReturnAccessor</c-></code> is to give implementations freedom to
optimize applying <code class="highlight"><c- n>accessor_conjugate</c-></code> twice in a row.  However,
implementations are not required to optimize arbitrary combinations of
nested <code class="highlight"><c- n>accessor_conjugate</c-></code> interspersed with other nested accessors.</p>
   <p>--<em>end note]</em></p>
   <p>[<em>Example:</em></p>
<pre class="language-c++ highlight"><c- b>void</c-> <c- nf>test_conjugated_complex</c-><c- p>(</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- k>complex</c-><c- o>&lt;</c-><c- b>double</c-><c- o>></c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- mi>10</c-><c- o>>></c-> <c- n>a</c-><c- p>)</c->
<c- p>{</c->
  <c- k>auto</c-> <c- n>a_conj</c-> <c- o>=</c-> <c- n>conjugated</c-><c- p>(</c-><c- n>a</c-><c- p>);</c->
  <c- k>for</c-><c- p>(</c-><c- b>int</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>&lt;</c-> <c- n>a</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>);</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c-> <c- p>{</c->
    <c- n>assert</c-><c- p>(</c-><c- n>a_conj</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>==</c-> <c- n>conj</c-><c- p>(</c-><c- n>a</c-><c- p>[</c-><c- n>i</c-><c- p>]);</c->
  <c- p>}</c->
  <c- k>auto</c-> <c- n>a_conj_conj</c-> <c- o>=</c-> <c- n>conjugated</c-><c- p>(</c-><c- n>a_conj</c-><c- p>);</c->
  <c- k>for</c-><c- p>(</c-><c- b>int</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>&lt;</c-> <c- n>a</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>);</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c-> <c- p>{</c->
    <c- n>assert</c-><c- p>(</c-><c- n>a_conj_conj</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>==</c-> <c- n>a</c-><c- p>[</c-><c- n>i</c-><c- p>]);</c->
  <c- p>}</c->
<c- p>}</c->

<c- b>void</c-> <c- nf>test_conjugated_real</c-><c- p>(</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- mi>10</c-><c- o>>></c-> <c- n>a</c-><c- p>)</c->
<c- p>{</c->
  <c- k>auto</c-> <c- n>a_conj</c-> <c- o>=</c-> <c- n>conjugated</c-><c- p>(</c-><c- n>a</c-><c- p>);</c->
  <c- k>for</c-><c- p>(</c-><c- b>int</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>&lt;</c-> <c- n>a</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>);</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c-> <c- p>{</c->
    <c- n>assert</c-><c- p>(</c-><c- n>a_conj</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>==</c-> <c- n>a</c-><c- p>[</c-><c- n>i</c-><c- p>]);</c->
  <c- p>}</c->
  <c- k>auto</c-> <c- n>a_conj_conj</c-> <c- o>=</c-> <c- n>conjugated</c-><c- p>(</c-><c- n>a_conj</c-><c- p>);</c->
  <c- k>for</c-><c- p>(</c-><c- b>int</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>&lt;</c-> <c- n>a</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>);</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c-> <c- p>{</c->
    <c- n>assert</c-><c- p>(</c-><c- n>a_conj_conj</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>==</c-> <c- n>a</c-><c- p>[</c-><c- n>i</c-><c- p>]);</c->
  <c- p>}</c->
<c- p>}</c->
</pre>
   --<em>end example</em>] 
   <h3 class="heading settled" data-level="16.7" id="transpose-in-place-transformation-linalgtransp"><span class="secno">16.7. </span><span class="content">Transpose in-place transformation [linalg.transp]</span><a class="self-link" href="#transpose-in-place-transformation-linalgtransp"></a></h3>
   <p><code class="highlight"><c- n>layout_transpose</c-></code> is an <code class="highlight"><c- n>mdspan</c-></code> layout mapping policy that
swaps the rightmost two indices, extents, and strides (if applicable)
of any unique <code class="highlight"><c- n>mdspan</c-></code> layout mapping policy.</p>
   <p>The <code class="highlight"><c- n>transposed</c-></code> function takes a rank-2 <code class="highlight"><c- n>mdspan</c-></code> representing a matrix, and returns a new read-only <code class="highlight"><c- n>mdspan</c-></code> representing the transpose of the input matrix.</p>
   <p><em>[Note:</em></p>
   <p>An implementation could dispatch to a function in the BLAS library, by
noticing that the first argument has a <code class="highlight"><c- n>layout_transpose</c-></code> <code class="highlight"><c- n>Layout</c-></code> type, and/or an <code class="highlight"><c- n>accessor_conjugate</c-></code> (see below) <code class="highlight"><c- n>Accessor</c-></code> type.  It
could use this information to extract the appropriate run-time
value(s) of the relevant <code class="highlight"><c- n>TRANS</c-><c- o>*</c-></code> BLAS function arguments.</p>
   <p>--<em>end note]</em></p>
   <h4 class="heading settled" data-level="16.7.1" id="layout_transpose-linalgtransplayout_transpose"><span class="secno">16.7.1. </span><span class="content"><code class="highlight"><c- n>layout_transpose</c-></code> [linalg.transp.layout_transpose]</span><a class="self-link" href="#layout_transpose-linalgtransplayout_transpose"></a></h4>
   <p><code class="highlight"><c- n>layout_transpose</c-></code> is an <code class="highlight"><c- n>mdspan</c-></code> layout mapping policy that
swaps the rightmost two indices, extents, and strides (if applicable)
of any unique <code class="highlight"><c- n>mdspan</c-></code> layout mapping policy.</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>InputExtents</c-><c- o>></c->
<c- n>using</c-> <c- n>transpose_extents_t</c-> <c- o>=</c-> <c- d>/* see below */</c-><c- p>;</c-> <c- c1>// exposition only</c->
</pre>
   <p>For <code class="highlight"><c- n>InputExtents</c-></code> a specialization of <code class="highlight"><c- n>extents</c-></code>, <code class="highlight"><c- n>transpose_extents_t</c-><c- o>&lt;</c-><c- n>InputExtents</c-><c- o>></c-></code> names the <code class="highlight"><c- n>extents</c-></code> type <code class="highlight"><c- n>OutputExtents</c-></code> such that</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>InputExtents</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- n>InputExtents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-><c- mi>-1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>OutputExtents</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- n>OutputExtents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-><c- mi>-2</c-><c- p>)</c-></code>,</p>
    <li data-md>
     <p><code class="highlight"><c- n>InputExtents</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- n>InputExtents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-><c- mi>-2</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>OutputExtents</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- n>OutputExtents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-><c- mi>-1</c-><c- p>)</c-></code>, and</p>
    <li data-md>
     <p><code class="highlight"><c- n>InputExtents</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>OutputExtents</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> for 0 ≤ <code class="highlight"><c- n>r</c-></code> &lt; <code class="highlight"><c- n>InputExtents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-><c- mi>-2</c-></code>.</p>
    <li data-md>
     <p><em>Preconditions:</em> <code class="highlight"><c- n>InputExtents</c-></code> is a specialization of <code class="highlight"><c- n>extents</c-></code>.</p>
    <li data-md>
     <p><em>Constraints:</em> <code class="highlight"><c- n>InputExtents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals 2.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>InputExtents</c-><c- o>></c->
<c- n>transpose_extents_t</c-><c- o>&lt;</c-><c- n>InputExtents</c-><c- o>></c->
<c- n>transpose_extents</c-><c- p>(</c-><c- k>const</c-> <c- n>InputExtents</c-> <c- n>in</c-><c- p>);</c-> <c- c1>// exposition only</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Constraints:</em> <code class="highlight"><c- n>InputExtents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals 2.</p>
    <li data-md>
     <p><em>Returns:</em> An <code class="highlight"><c- n>extents</c-></code> object <code class="highlight"><c- n>out</c-></code> such that</p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>out</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>in</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-><c- mi>-1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>in</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>in</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-><c- mi>-2</c-><c- p>)</c-></code>,</p>
      <li data-md>
       <p><code class="highlight"><c- n>out</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>in</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-><c- mi>-2</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>in</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>in</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-><c- mi>-1</c-><c- p>)</c-></code>, and</p>
      <li data-md>
       <p><code class="highlight"><c- n>out</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>in</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> for 0 ≤ <code class="highlight"><c- n>r</c-></code> &lt; <code class="highlight"><c- n>in</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-><c- mi>-2</c-></code>.</p>
     </ul>
   </ul>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Layout</c-><c- o>></c->
<c- n>class</c-> <c- n>layout_transpose</c-> <c- p>{</c->
<c- nl>public</c-><c- p>:</c->
  <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Extents</c-><c- o>></c->
  <c- k>struct</c-> <c- nc>mapping</c-> <c- p>{</c->
  <c- nl>private</c-><c- p>:</c->
    <c- n>using</c-> <c- n>nested_mapping_type</c-> <c- o>=</c->
      <c- n>typename</c-> <c- n>Layout</c-><c- o>::</c-><c- n>template</c-> <c- n>mapping</c-><c- o>&lt;</c->
        <c- n>transpose_extents_t</c-><c- o>&lt;</c-><c- n>Extents</c-><c- o>>></c-><c- p>;</c-> <c- c1>// exposition only</c->
    <c- n>nested_mapping_type</c-> <c- n>nested_mapping_</c-><c- p>;</c-> <c- c1>// exposition only</c->

  <c- nl>public</c-><c- p>:</c->
    <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>nested_mapping_type</c-><c- o>&amp;</c-> <c- n>map</c-><c- p>);</c->

    <c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>operator</c-><c- p>()</c-> <c- p>(</c->
      <c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>i</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>j</c-><c- p>)</c-> <c- k>const</c->
        <c- n>noexcept</c-><c- p>(</c-><c- n>noexcept</c-><c- p>(</c-><c- n>nested_mapping_</c-><c- p>(</c-><c- n>j</c-><c- p>,</c-> <c- n>i</c-><c- p>)));</c->

    <c- n>nested_mapping_type</c-> <c- nf>nested_mapping</c-><c- p>()</c-> <c- k>const</c-><c- p>;</c->

    <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
    <c- b>bool</c-> <c- n>operator</c-><c- o>==</c-><c- p>(</c-><c- k>const</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>m</c-><c- p>)</c-> <c- k>const</c-><c- p>;</c->

    <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
    <c- b>bool</c-> <c- n>operator</c-><c- o>!=</c-><c- p>(</c-><c- k>const</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>m</c-><c- p>)</c-> <c- k>const</c-><c- p>;</c->

    <c- n>Extents</c-> <c- nf>extents</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c-> <c- n>required_span_size</c-><c- p>()</c-> <c- k>const</c->
      <c- n>noexcept</c-><c- p>(</c-><c- n>noexcept</c-><c- p>(</c-><c- n>nested_mapping_</c-><c- p>.</c-><c- n>required_span_size</c-><c- p>()));</c->

    <c- b>bool</c-> <c- nf>is_unique</c-><c- p>()</c-> <c- k>const</c->
      <c- n>noexcept</c-><c- p>(</c-><c- n>noexcept</c-><c- p>(</c-><c- n>nested_mapping_</c-><c- p>.</c-><c- n>is_unique</c-><c- p>()));</c->

    <c- b>bool</c-> <c- nf>is_contiguous</c-><c- p>()</c-> <c- k>const</c->
      <c- n>noexcept</c-><c- p>(</c-><c- n>noexcept</c-><c- p>(</c-><c- n>nested_mapping_</c-><c- p>.</c-><c- n>is_contiguous</c-><c- p>()));</c->

    <c- b>bool</c-> <c- nf>is_strided</c-><c- p>()</c-> <c- k>const</c->
      <c- n>noexcept</c-><c- p>(</c-><c- n>noexcept</c-><c- p>(</c-><c- n>nested_mapping_</c-><c- p>.</c-><c- n>is_strided</c-><c- p>()));</c->

    <c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_unique</c-><c- p>();</c->

    <c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_contiguous</c-><c- p>();</c->

    <c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_strided</c-><c- p>();</c->

    <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c->
    <c- n>stride</c-><c- p>(</c-><c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c-> <c- n>r</c-><c- p>)</c-> <c- k>const</c->
      <c- n>noexcept</c-><c- p>(</c-><c- n>noexcept</c-><c- p>(</c-><c- n>nested_mapping_</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- n>r</c-><c- p>)));</c->
  <c- p>};</c->
<c- p>};</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> <code class="highlight"><c- n>Layout</c-></code> shall meet the <code class="highlight"><c- n>mdspan</c-></code> layout mapping policy requirements.</p>
    <li data-md>
     <p><em>Constraints:</em> For all specializations <code class="highlight"><c- n>E</c-></code> of <code class="highlight"><c- n>extents</c-></code> with <code class="highlight"><c- n>E</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equal to 2, <code class="highlight"><c- k>typename</c-> <c- nc>Layout</c-><c- o>::</c-><c- k>template</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>E</c-><c- o>>::</c-><c- n>is_always_unique</c-><c- p>()</c-></code> is <code class="highlight">true</code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>nested_mapping_type</c-><c- o>&amp;</c-> <c- n>map</c-><c- p>);</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Initializes <code class="highlight"><c- n>nested_mapping_</c-></code> with <code class="highlight"><c- n>map</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>operator</c-><c- p>()</c-> <c- p>(</c->
  <c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>i</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>j</c-><c- p>)</c-> <c- k>const</c->
    <c- n>noexcept</c-><c- p>(</c-><c- n>noexcept</c-><c- p>(</c-><c- n>nested_mapping_</c-><c- p>(</c-><c- n>j</c-><c- p>,</c-> <c- n>i</c-><c- p>)));</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- nf>nested_mapping_</c-><c- p>(</c-><c- n>j</c-><c- p>,</c-> <c- n>i</c-><c- p>);</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>nested_mapping_type</c-> <c- nf>nested_mapping</c-><c- p>()</c-> <c- k>const</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- n>nested_mapping_</c-><c- p>;</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
<c- b>bool</c-> <c- n>operator</c-><c- o>==</c-><c- p>(</c-><c- k>const</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>m</c-><c- p>)</c-> <c- k>const</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Constraints:</em> <code class="highlight"><c- n>OtherExtents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals <code class="highlight"><c- n>rank</c-><c- p>()</c-></code>.</p>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- n>nested_mapping_</c-> <c- o>==</c-> <c- n>m</c-><c- p>.</c-><c- n>nested_mapping_</c-><c- p>;</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
<c- b>bool</c-> <c- n>operator</c-><c- o>!=</c-><c- p>(</c-><c- k>const</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>m</c-><c- p>)</c-> <c- k>const</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Constraints:</em> <code class="highlight"><c- n>OtherExtents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals <code class="highlight"><c- n>rank</c-><c- p>()</c-></code>.</p>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- n>nested_mapping_</c-> <c- o>!=</c-> <c- n>m</c-><c- p>.</c-><c- n>nested_mapping_</c-><c- p>;</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>Extents</c-> <c- nf>extents</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- nf>transpose_extents</c-><c- p>(</c-><c- n>nested_mapping_</c-><c- p>.</c-><c- n>extents</c-><c- p>());</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c->
<c- n>required_span_size</c-><c- p>()</c-> <c- k>const</c->
  <c- n>noexcept</c-><c- p>(</c-><c- n>noexcept</c-><c- p>(</c-><c- n>nested_mapping_</c-><c- p>.</c-><c- n>required_span_size</c-><c- p>()));</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- n>nested_mapping_</c-><c- p>.</c-><c- n>required_span_size</c-><c- p>();</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- b>bool</c-> <c- nf>is_unique</c-><c- p>()</c-> <c- k>const</c->
  <c- n>noexcept</c-><c- p>(</c-><c- n>noexcept</c-><c- p>(</c-><c- n>nested_mapping_</c-><c- p>.</c-><c- n>is_unique</c-><c- p>()));</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- n>nested_mapping_</c-><c- p>.</c-><c- n>is_unique</c-><c- p>();</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- b>bool</c-> <c- nf>is_contiguous</c-><c- p>()</c-> <c- k>const</c->
  <c- n>noexcept</c-><c- p>(</c-><c- n>noexcept</c-><c- p>(</c-><c- n>nested_mapping_</c-><c- p>.</c-><c- n>is_contiguous</c-><c- p>()));</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- n>nested_mapping_</c-><c- p>.</c-><c- n>is_contiguous</c-><c- p>();</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- b>bool</c-> <c- nf>is_strided</c-><c- p>()</c-> <c- k>const</c->
  <c- n>noexcept</c-><c- p>(</c-><c- n>noexcept</c-><c- p>(</c-><c- n>nested_mapping_</c-><c- p>.</c-><c- n>is_strided</c-><c- p>()));</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- n>nested_mapping_</c-><c- p>.</c-><c- n>is_strided</c-><c- p>();</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_unique</c-><c- p>();</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- n>nested_mapping_type</c-><c- o>::</c-><c- n>is_always_unique</c-><c- p>();</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_contiguous</c-><c- p>();</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- n>nested_mapping_type</c-><c- o>::</c-><c- n>is_always_contiguous</c-><c- p>();</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_strided</c-><c- p>();</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- n>nested_mapping_type</c-><c- o>::</c-><c- n>is_always_strided</c-><c- p>();</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c->
<c- n>stride</c-><c- p>(</c-><c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>size_type</c-> <c- n>r</c-><c- p>)</c-> <c- k>const</c->
  <c- n>noexcept</c-><c- p>(</c-><c- n>noexcept</c-><c- p>(</c-><c- n>nested_mapping_</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- n>r</c-><c- p>)));</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Constraints:</em> <code class="highlight"><c- n>is_always_strided</c-><c- p>()</c-></code> is <code class="highlight">true</code>.</p>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- n>nested_mapping_</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- n>s</c-><c- p>);</c-></code>,
where <code class="highlight"><c- n>s</c-></code> is 0 if <code class="highlight"><c- n>r</c-></code> is 1 and <code class="highlight"><c- n>s</c-></code> is 1 if <code class="highlight"><c- n>r</c-></code> is 0.</p>
   </ul>
   <h4 class="heading settled" data-level="16.7.2" id="transposed-linalgtransptransposed"><span class="secno">16.7.2. </span><span class="content"><code class="highlight"><c- n>transposed</c-></code> [linalg.transp.transposed]</span><a class="self-link" href="#transposed-linalgtransptransposed"></a></h4>
   <p>The <code class="highlight"><c- n>transposed</c-></code> function takes a rank-2 <code class="highlight"><c- n>mdspan</c-></code> representing a matrix, and returns a new read-only <code class="highlight"><c- n>mdspan</c-></code> representing the transpose of the input matrix.  The input matrix’s
data are not modified, and the returned <code class="highlight"><c- n>mdspan</c-></code> accesses the
input matrix’s data in place.  If the input <code class="highlight"><c- n>mdspan</c-></code>'s layout is
already <code class="highlight"><c- n>layout_transpose</c-><c- o>&lt;</c-><c- n>L</c-><c- o>></c-></code> for some layout <code class="highlight"><c- n>L</c-></code>, then the returned <code class="highlight"><c- n>mdspan</c-></code> has layout <code class="highlight"><c- n>L</c-></code>.  Otherwise, the returned <code class="highlight"><c- n>mdspan</c-></code> has layout <code class="highlight"><c- n>layout_transpose</c-><c- o>&lt;</c-><c- n>L</c-><c- o>></c-></code>, where <code class="highlight"><c- n>L</c-></code> is the input <code class="highlight"><c- n>mdspan</c-></code>'s layout.</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ElementType</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Extents</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Layout</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Accessor</c-><c- o>></c->
<c- d>/* see-below */</c->
<c- n>transposed</c-><c- p>(</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- n>ElementType</c-><c- p>,</c-> <c- n>Extents</c-><c- p>,</c-> <c- n>Layout</c-><c- p>,</c-> <c- n>Accessor</c-><c- o>></c-> <c- n>a</c-><c- p>);</c->
</pre>
   <p>Let <code class="highlight"><c- n>ReturnExtents</c-></code> name the type <code class="highlight"><c- n>transpose_extents_t</c-><c- o>&lt;</c-><c- n>Extents</c-><c- o>></c-></code>.
Let <code class="highlight"><c- n>R</c-></code> name the type <code class="highlight"><c- n>mdspan</c-><c- o>&lt;</c-><c- n>ReturnElementType</c-><c- p>,</c-> <c- n>ReturnExtents</c-><c- p>,</c-> <c- n>ReturnLayout</c-><c- p>,</c-> <c- n>Accessor</c-><c- o>></c-></code>,
where</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>ReturnElementType</c-></code> is either <code class="highlight"><c- n>ElementType</c-></code> or <code class="highlight"><c- k>const</c-> <c- n>ElementType</c-></code>; and</p>
    <li data-md>
     <p><code class="highlight"><c- n>ReturnLayout</c-></code> is:</p>
     <ul>
      <li data-md>
       <p>if <code class="highlight"><c- n>Layout</c-></code> is <code class="highlight"><c- n>layout_blas_packed</c-><c- o>&lt;</c-><c- n>Triangle</c-><c- p>,</c-> <c- n>StorageOrder</c-><c- o>></c-></code>,
then <code class="highlight"><c- n>layout_blas_packed</c-><c- o>&lt;</c-><c- n>OppositeTriangle</c-><c- p>,</c-> <c- n>OppositeStorageOrder</c-><c- o>></c-></code>,
where</p>
       <ul>
        <li data-md>
         <p><code class="highlight"><c- n>OppositeTriangle</c-></code> names the type <code class="highlight"><c- n>conditional_t</c-><c- o>&lt;</c-><c- n>is_same_v</c-><c- o>&lt;</c-><c- n>Triangle</c-><c- p>,</c-> <c- n>upper_triangle_t</c-><c- o>></c-><c- p>,</c-> <c- n>lower_triangle_t</c-><c- p>,</c-> <c- n>upper_triangle_t</c-><c- o>></c-></code>, and</p>
        <li data-md>
         <p><code class="highlight"><c- n>OppositeStorageOrder</c-></code> names the type <code class="highlight"><c- n>conditional_t</c-><c- o>&lt;</c-><c- n>is_same_v</c-><c- o>&lt;</c-><c- n>StorageOrder</c-><c- p>,</c-> <c- n>column_major_t</c-><c- o>></c-><c- p>,</c-> <c- n>row_major_t</c-><c- p>,</c-> <c- n>column_major_t</c-><c- o>></c-></code>;</p>
       </ul>
      <li data-md>
       <p>else, if <code class="highlight"><c- n>Layout</c-></code> is <code class="highlight"><c- n>layout_transpose</c-><c- o>&lt;</c-><c- n>NestedLayout</c-><c- o>></c-></code> for some <code class="highlight"><c- n>NestedLayout</c-></code>, then
either <code class="highlight"><c- n>NestedLayout</c-></code> or <code class="highlight"><c- n>layout_transpose</c-><c- o>&lt;</c-><c- n>Layout</c-><c- o>></c-></code>,</p>
      <li data-md>
       <p>else <code class="highlight"><c- n>layout_transpose</c-><c- o>&lt;</c-><c- n>Layout</c-><c- o>></c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Effects:</em></p>
     <ul>
      <li data-md>
       <p>If <code class="highlight"><c- n>Layout</c-></code> is <code class="highlight"><c- n>layout_blas_packed</c-><c- o>&lt;</c-><c- n>Triangle</c-><c- p>,</c-> <c- n>StorageOrder</c-><c- o>></c-></code>,
then equivalent to <code class="highlight"><c- k>return</c-> <c- nf>R</c-><c- p>(</c-><c- n>a</c-><c- p>.</c-><c- n>data</c-><c- p>(),</c-> <c- n>ReturnMapping</c-><c- p>(</c-><c- n>a</c-><c- p>.</c-><c- n>mapping</c-><c- p>().</c-><c- n>extents</c-><c- p>()),</c-> <c- n>a</c-><c- p>.</c-><c- n>accessor</c-><c- p>());</c-></code>;</p>
      <li data-md>
       <p>else, if <code class="highlight"><c- n>Layout</c-></code> is <code class="highlight"><c- n>layout_transpose</c-><c- o>&lt;</c-><c- n>NestedLayout</c-><c- o>></c-></code> and <code class="highlight"><c- n>ReturnLayout</c-></code> is <code class="highlight"><c- n>NestedLayout</c-></code>, then equivalent to <code class="highlight"><c- k>return</c-> <c- nf>R</c-><c- p>(</c-><c- n>a</c-><c- p>.</c-><c- n>data</c-><c- p>(),</c-> <c- n>a</c-><c- p>.</c-><c- n>mapping</c-><c- p>().</c-><c- n>nested_mapping</c-><c- p>(),</c-> <c- n>a</c-><c- p>.</c-><c- n>accessor</c-><c- p>());</c-></code>;</p>
      <li data-md>
       <p>else, equivalent to <code class="highlight"><c- k>return</c-> <c- nf>R</c-><c- p>(</c-><c- n>a</c-><c- p>.</c-><c- n>data</c-><c- p>(),</c-> <c- n>ReturnMapping</c-><c- p>(</c-><c- n>a</c-><c- p>.</c-><c- n>mapping</c-><c- p>()),</c-> <c- n>a</c-><c- p>.</c-><c- n>accessor</c-><c- p>);</c-></code>,
where <code class="highlight"><c- n>ReturnMapping</c-></code> names the type <code class="highlight"><c- k>typename</c-> <c- nc>layout_transpose</c-><c- o>&lt;</c-><c- n>Layout</c-><c- o>>::</c-><c- k>template</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>ReturnExtents</c-><c- o>></c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Remarks:</em> The elements of the returned <code class="highlight"><c- n>mdspan</c-></code> are read only.</p>
   </ul>
   <p><em>[Note:</em></p>
   <p>Implementations may optimize applying <code class="highlight"><c- n>layout_transpose</c-></code> twice in a
row.  However, implementations need not optimize arbitrary
combinations of nested <code class="highlight"><c- n>layout_transpose</c-></code> interspersed with other
nested layouts.</p>
   <p>--<em>end note]</em></p>
   <p>[<em>Example:</em></p>
<pre class="language-c++ highlight"><c- b>void</c-> <c- nf>test_transposed</c-><c- p>(</c-><c- n>mdspan</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- mi>3</c-><c- p>,</c-> <c- mi>4</c-><c- o>>></c-> <c- n>a</c-><c- p>)</c->
<c- p>{</c->
  <c- k>const</c-> <c- k>auto</c-> <c- n>num_rows</c-> <c- o>=</c-> <c- n>a</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>);</c->
  <c- k>const</c-> <c- k>auto</c-> <c- n>num_cols</c-> <c- o>=</c-> <c- n>a</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>);</c->

  <c- k>auto</c-> <c- n>a_t</c-> <c- o>=</c-> <c- n>transposed</c-><c- p>(</c-><c- n>a</c-><c- p>);</c->
  <c- n>assert</c-><c- p>(</c-><c- n>num_rows</c-> <c- o>==</c-> <c- n>a_t</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>));</c->
  <c- n>assert</c-><c- p>(</c-><c- n>num_cols</c-> <c- o>==</c-> <c- n>a_t</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>));</c->
  <c- n>assert</c-><c- p>(</c-><c- n>a</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-> <c- o>==</c-> <c- n>a_t</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>));</c->
  <c- n>assert</c-><c- p>(</c-><c- n>a</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-> <c- o>==</c-> <c- n>a_t</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>0</c-><c- p>));</c->

  <c- k>for</c-><c- p>(</c-><c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>row</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>row</c-> <c- o>&lt;</c-> <c- n>num_rows</c-><c- p>;</c-> <c- o>++</c-><c- n>row</c-><c- p>)</c-> <c- p>{</c->
    <c- k>for</c-><c- p>(</c-><c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>col</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>col</c-> <c- o>&lt;</c-> <c- n>num_rows</c-><c- p>;</c-> <c- o>++</c-><c- n>col</c-><c- p>)</c-> <c- p>{</c->
      <c- n>assert</c-><c- p>(</c-><c- n>a</c-><c- p>[</c-><c- n>row</c-><c- p>,</c-> <c- n>col</c-><c- p>]</c-> <c- o>==</c-> <c- n>a_t</c-><c- p>[</c-><c- n>col</c-><c- p>,</c-> <c- n>row</c-><c- p>]);</c->
    <c- p>}</c->
  <c- p>}</c->

  <c- k>auto</c-> <c- n>a_t_t</c-> <c- o>=</c-> <c- n>transposed</c-><c- p>(</c-><c- n>a_t</c-><c- p>);</c->
  <c- n>assert</c-><c- p>(</c-><c- n>num_rows</c-> <c- o>==</c-> <c- n>a_t_t</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>));</c->
  <c- n>assert</c-><c- p>(</c-><c- n>num_cols</c-> <c- o>==</c-> <c- n>a_t_t</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>));</c->
  <c- n>assert</c-><c- p>(</c-><c- n>a</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-> <c- o>==</c-> <c- n>a_t_t</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>0</c-><c- p>));</c->
  <c- n>assert</c-><c- p>(</c-><c- n>a</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-> <c- o>==</c-> <c- n>a_t_t</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>));</c->

  <c- k>for</c-><c- p>(</c-><c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>row</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>row</c-> <c- o>&lt;</c-> <c- n>num_rows</c-><c- p>;</c-> <c- o>++</c-><c- n>row</c-><c- p>)</c-> <c- p>{</c->
    <c- k>for</c-><c- p>(</c-><c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>col</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>col</c-> <c- o>&lt;</c-> <c- n>num_rows</c-><c- p>;</c-> <c- o>++</c-><c- n>col</c-><c- p>)</c-> <c- p>{</c->
      <c- n>assert</c-><c- p>(</c-><c- n>a</c-><c- p>[</c-><c- n>row</c-><c- p>,</c-> <c- n>col</c-><c- p>]</c-> <c- o>==</c-> <c- n>a_t_t</c-><c- p>[</c-><c- n>row</c-><c- p>,</c-> <c- n>col</c-><c- p>]);</c->
    <c- p>}</c->
  <c- p>}</c->
<c- p>}</c->
</pre>
   --<em>end example</em>] 
   <h3 class="heading settled" data-level="16.8" id="conjugate-transpose-transform-linalgconj_transp"><span class="secno">16.8. </span><span class="content">Conjugate transpose transform [linalg.conj_transp]</span><a class="self-link" href="#conjugate-transpose-transform-linalgconj_transp"></a></h3>
   <p>The <code class="highlight"><c- n>conjugate_transposed</c-></code> function returns a conjugate transpose
view of an object.  This combines the effects of <code class="highlight"><c- n>transposed</c-></code> and <code class="highlight"><c- n>conjugated</c-></code>.</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ElementType</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Extents</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Layout</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Accessor</c-><c- o>></c->
<c- d>/* see-below */</c->
<c- n>conjugate_transposed</c-><c- p>(</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- n>ElementType</c-><c- p>,</c-> <c- n>Extents</c-><c- p>,</c-> <c- n>Layout</c-><c- p>,</c-> <c- n>Accessor</c-><c- o>></c-> <c- n>a</c-><c- p>);</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-> <c- nf>conjugated</c-><c- p>(</c-><c- n>transposed</c-><c- p>(</c-><c- n>a</c-><c- p>));</c-></code>.</p>
    <li data-md>
     <p><em>Remarks:</em> The elements of the returned <code class="highlight"><c- n>mdspan</c-></code> are read only.</p>
   </ul>
   <p>[<em>Example:</em></p>
<pre class="language-c++ highlight"><c- b>void</c-> <c- nf>test_conjugate_transposed</c-><c- p>(</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- k>complex</c-><c- o>&lt;</c-><c- b>double</c-><c- o>></c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- mi>3</c-><c- p>,</c-> <c- mi>4</c-><c- o>>></c-> <c- n>a</c-><c- p>)</c->
<c- p>{</c->
  <c- k>const</c-> <c- k>auto</c-> <c- n>num_rows</c-> <c- o>=</c-> <c- n>a</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>);</c->
  <c- k>const</c-> <c- k>auto</c-> <c- n>num_cols</c-> <c- o>=</c-> <c- n>a</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>);</c->

  <c- k>auto</c-> <c- n>a_ct</c-> <c- o>=</c-> <c- n>conjugate_transposed</c-><c- p>(</c-><c- n>a</c-><c- p>);</c->
  <c- n>assert</c-><c- p>(</c-><c- n>num_rows</c-> <c- o>==</c-> <c- n>a_ct</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>));</c->
  <c- n>assert</c-><c- p>(</c-><c- n>num_cols</c-> <c- o>==</c-> <c- n>a_ct</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>));</c->
  <c- n>assert</c-><c- p>(</c-><c- n>a</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-> <c- o>==</c-> <c- n>a_ct</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>));</c->
  <c- n>assert</c-><c- p>(</c-><c- n>a</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-> <c- o>==</c-> <c- n>a_ct</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>0</c-><c- p>));</c->

  <c- k>for</c-><c- p>(</c-><c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>row</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>row</c-> <c- o>&lt;</c-> <c- n>num_rows</c-><c- p>;</c-> <c- o>++</c-><c- n>row</c-><c- p>)</c-> <c- p>{</c->
    <c- k>for</c-><c- p>(</c-><c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>col</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>col</c-> <c- o>&lt;</c-> <c- n>num_rows</c-><c- p>;</c-> <c- o>++</c-><c- n>col</c-><c- p>)</c-> <c- p>{</c->
      <c- n>assert</c-><c- p>(</c-><c- n>a</c-><c- p>[</c-><c- n>row</c-><c- p>,</c-> <c- n>col</c-><c- p>]</c-> <c- o>==</c-> <c- n>conj</c-><c- p>(</c-><c- n>a_ct</c-><c- p>[</c-><c- n>col</c-><c- p>,</c-> <c- n>row</c-><c- p>]));</c->
    <c- p>}</c->
  <c- p>}</c->

  <c- k>auto</c-> <c- n>a_ct_ct</c-> <c- o>=</c-> <c- n>conjugate_transposed</c-><c- p>(</c-><c- n>a_ct</c-><c- p>);</c->
  <c- n>assert</c-><c- p>(</c-><c- n>num_rows</c-> <c- o>==</c-> <c- n>a_ct_ct</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>));</c->
  <c- n>assert</c-><c- p>(</c-><c- n>num_cols</c-> <c- o>==</c-> <c- n>a_ct_ct</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>));</c->
  <c- n>assert</c-><c- p>(</c-><c- n>a</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-> <c- o>==</c-> <c- n>a_ct_ct</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>0</c-><c- p>));</c->
  <c- n>assert</c-><c- p>(</c-><c- n>a</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-> <c- o>==</c-> <c- n>a_ct_ct</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>));</c->

  <c- k>for</c-><c- p>(</c-><c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>row</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>row</c-> <c- o>&lt;</c-> <c- n>num_rows</c-><c- p>;</c-> <c- o>++</c-><c- n>row</c-><c- p>)</c-> <c- p>{</c->
    <c- k>for</c-><c- p>(</c-><c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>col</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>col</c-> <c- o>&lt;</c-> <c- n>num_rows</c-><c- p>;</c-> <c- o>++</c-><c- n>col</c-><c- p>)</c-> <c- p>{</c->
      <c- n>assert</c-><c- p>(</c-><c- n>a</c-><c- p>[</c-><c- n>row</c-><c- p>,</c-> <c- n>col</c-><c- p>]</c-> <c- o>==</c-> <c- n>a_ct_ct</c-><c- p>[</c-><c- n>row</c-><c- p>,</c-> <c- n>col</c-><c- p>]);</c->
      <c- n>assert</c-><c- p>(</c-><c- n>conj</c-><c- p>(</c-><c- n>a_ct</c-><c- p>[</c-><c- n>col</c-><c- p>,</c-> <c- n>row</c-><c- p>])</c-> <c- o>==</c-> <c- n>a_ct_ct</c-><c- p>[</c-><c- n>row</c-><c- p>,</c-> <c- n>col</c-><c- p>]);</c->
    <c- p>}</c->
  <c- p>}</c->
<c- p>}</c->
</pre>
   --<em>end example</em>] 
   <h3 class="heading settled" data-level="16.9" id="algorithms-linalgalgs"><span class="secno">16.9. </span><span class="content">Algorithms [linalg.algs]</span><a class="self-link" href="#algorithms-linalgalgs"></a></h3>
   <h4 class="heading settled" data-level="16.9.1" id="requirements-based-on-template-parameter-name-linalgalgsreqs"><span class="secno">16.9.1. </span><span class="content">Requirements based on template parameter name [linalg.algs.reqs]</span><a class="self-link" href="#requirements-based-on-template-parameter-name-linalgalgsreqs"></a></h4>
   <p>Throughout this Clause, where the template parameters are not
constrained, the names of template parameters are used to express type
requirements.  In the requirements below, we use <code class="highlight"><c- o>*</c-></code> in a typename to
denote a "wildcard," that matches zero characters, <code class="highlight"><c- n>_1</c-></code>, <code class="highlight"><c- n>_2</c-></code>, <code class="highlight"><c- n>_3</c-></code>,
or other things as appropriate.</p>
   <ul>
    <li data-md>
     <p>Algorithms that have a template parameter named <code class="highlight"><c- n>ExecutionPolicy</c-></code> are parallel algorithms <strong>[algorithms.parallel.defns]</strong>.</p>
    <li data-md>
     <p><code class="highlight"><c- n>Real</c-></code> is any type such that <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- n>Real</c-><c- o>></c-></code> is specified. <em>[Note:</em> See <strong>[complex.numbers.general]</strong>. --<em>end note]</em></p>
    <li data-md>
     <p><code class="highlight"><c- n>in_vector</c-><c- o>*</c-><c- n>_t</c-></code> is a rank-1 <code class="highlight"><c- n>mdspan</c-></code> with a
potentially <code class="highlight"><c- k>const</c-></code> element type and a unique layout.
If the algorithm accesses the object, it will do so in read-only fashion.</p>
    <li data-md>
     <p><code class="highlight"><c- n>inout_vector</c-><c- o>*</c-><c- n>_t</c-></code> is a rank-1 <code class="highlight"><c- n>mdspan</c-></code> with a non-<code class="highlight"><c- k>const</c-></code> element type,
and whose layout is always unique
(<code class="highlight"><c- n>layout_type</c-><c- o>::</c-><c- n>is_always_unique</c-><c- p>()</c-></code> equals <code class="highlight">true</code>).</p>
    <li data-md>
     <p><code class="highlight"><c- n>out_vector</c-><c- o>*</c-><c- n>_t</c-></code> is a rank-1 <code class="highlight"><c- n>mdspan</c-></code> with a non-<code class="highlight"><c- k>const</c-></code> element type,
and whose layout is always unique
(<code class="highlight"><c- n>layout_type</c-><c- o>::</c-><c- n>is_always_unique</c-><c- p>()</c-></code> equals <code class="highlight">true</code>).
If the algorithm accesses the object, it will do so in write-only fashion.</p>
    <li data-md>
     <p><code class="highlight"><c- n>in_matrix</c-><c- o>*</c-><c- n>_t</c-></code> is a rank-2 <code class="highlight"><c- n>mdspan</c-></code> with a <code class="highlight"><c- k>const</c-></code> element type.
If the algorithm accesses the object, it will do so in read-only fashion.</p>
    <li data-md>
     <p><code class="highlight"><c- n>inout_matrix</c-><c- o>*</c-><c- n>_t</c-></code> is a rank-2 <code class="highlight"><c- n>mdspan</c-></code> with a non-<code class="highlight"><c- k>const</c-></code> element type.</p>
    <li data-md>
     <p><code class="highlight"><c- n>out_matrix</c-><c- o>*</c-><c- n>_t</c-></code> is a rank-2 <code class="highlight"><c- n>mdspan</c-></code> with
a non-<code class="highlight"><c- k>const</c-></code> element type.
If the algorithm accesses the object, it will do so in write-only fashion.</p>
    <li data-md>
     <p><code class="highlight"><c- n>in_object</c-><c- o>*</c-><c- n>_t</c-></code> is a rank-1 or rank-2 <code class="highlight"><c- n>mdspan</c-></code> with a potentially <code class="highlight"><c- k>const</c-></code> element type,
and whose layout is always unique
(<code class="highlight"><c- n>layout_type</c-><c- o>::</c-><c- n>is_always_unique</c-><c- p>()</c-></code> equals <code class="highlight">true</code>).
If the algorithm accesses the object,
it will do so in read-only fashion.</p>
    <li data-md>
     <p><code class="highlight"><c- n>inout_object</c-><c- o>*</c-><c- n>_t</c-></code> is a rank-1 or rank-2 <code class="highlight"><c- n>mdspan</c-></code> with a non-<code class="highlight"><c- k>const</c-></code> element type,
and whose layout is always unique
(<code class="highlight"><c- n>layout_type</c-><c- o>::</c-><c- n>is_always_unique</c-><c- p>()</c-></code> equals <code class="highlight">true</code>).</p>
    <li data-md>
     <p><code class="highlight"><c- n>out_object</c-><c- o>*</c-><c- n>_t</c-></code> is a rank-1 or rank-2 <code class="highlight"><c- n>mdspan</c-></code> with a non-<code class="highlight"><c- k>const</c-></code> element type,
and whose layout is always unique
(<code class="highlight"><c- n>layout_type</c-><c- o>::</c-><c- n>is_always_unique</c-><c- p>()</c-></code> equals <code class="highlight">true</code>).</p>
    <li data-md>
     <p><code class="highlight"><c- n>Triangle</c-></code> is either <code class="highlight"><c- n>upper_triangle_t</c-></code> or <code class="highlight"><c- n>lower_triangle_t</c-></code>.</p>
    <li data-md>
     <p><code class="highlight"><c- n>DiagonalStorage</c-></code> is either <code class="highlight"><c- n>implicit_unit_diagonal_t</c-></code> or <code class="highlight"><c- n>explicit_diagonal_t</c-></code>.</p>
    <li data-md>
     <p><code class="highlight"><c- n>in_</c-><c- o>*</c-><c- n>_t</c-></code> template parameters may deduce a <code class="highlight"><c- k>const</c-></code> lvalue reference
or a (non-<code class="highlight"><c- k>const</c-></code>) rvalue reference to an <code class="highlight"><c- n>mdspan</c-></code>.</p>
    <li data-md>
     <p><code class="highlight"><c- n>inout_</c-><c- o>*</c-><c- n>_t</c-></code> and <code class="highlight"><c- n>out_</c-><c- o>*</c-><c- n>_t</c-></code> template parameters may deduce
a <code class="highlight"><c- k>const</c-></code> lvalue reference to an <code class="highlight"><c- n>mdspan</c-></code>, or
a (non-<code class="highlight"><c- k>const</c-></code>) rvalue reference to an <code class="highlight"><c- n>mdspan</c-></code>.</p>
   </ul>
   <h4 class="heading settled" data-level="16.9.2" id="blas-1-functions-linalgalgsblas1"><span class="secno">16.9.2. </span><span class="content">BLAS 1 functions [linalg.algs.blas1]</span><a class="self-link" href="#blas-1-functions-linalgalgsblas1"></a></h4>
   <p><em>[Note:</em></p>
   <p>The BLAS developed in three "levels": 1, 2, and 3.  BLAS 1 includes
vector-vector operations, BLAS 2 matrix-vector operations, and BLAS 3
matrix-matrix operations.  The level coincides with the number of
nested loops in a naïve sequential implementation of the operation.
Increasing level also comes with increasing potential for data reuse.
The BLAS traditionally lists computing a Givens rotation among the
BLAS 1 operations, even though it only operates on scalars.</p>
   <p>--<em>end note]</em></p>
   <p><em>Complexity:</em> All algorithms in this Clause with <code class="highlight"><c- n>mdspan</c-></code> parameters
perform a count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
that is linear in the maximum product of extents of any <code class="highlight"><c- n>mdspan</c-></code> parameter.</p>
   <h5 class="heading settled" data-level="16.9.2.1" id="givens-rotations-linalgalgsblas1givens"><span class="secno">16.9.2.1. </span><span class="content">Givens rotations [linalg.algs.blas1.givens]</span><a class="self-link" href="#givens-rotations-linalgalgsblas1givens"></a></h5>
   <h6 class="heading settled" data-level="16.9.2.1.1" id="compute-givens-rotation-linalgalgsblas1givenslartg"><span class="secno">16.9.2.1.1. </span><span class="content">Compute Givens rotation [linalg.algs.blas1.givens.lartg]</span><a class="self-link" href="#compute-givens-rotation-linalgalgsblas1givenslartg"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Real</c-><c- o>></c->
<c- b>void</c-> <c- n>givens_rotation_setup</c-><c- p>(</c-><c- k>const</c-> <c- n>Real</c-> <c- n>a</c-><c- p>,</c->
                           <c- k>const</c-> <c- n>Real</c-> <c- n>b</c-><c- p>,</c->
                           <c- n>Real</c-><c- o>&amp;</c-> <c- n>c</c-><c- p>,</c->
                           <c- n>Real</c-><c- o>&amp;</c-> <c- n>s</c-><c- p>,</c->
                           <c- n>Real</c-><c- o>&amp;</c-> <c- n>r</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Real</c-><c- o>></c->
<c- b>void</c-> <c- n>givens_rotation_setup</c-><c- p>(</c-><c- k>const</c-> <c- k>complex</c-><c- o>&lt;</c-><c- n>Real</c-><c- o>>&amp;</c-> <c- n>a</c-><c- p>,</c->
                           <c- k>const</c-> <c- k>complex</c-><c- o>&lt;</c-><c- n>Real</c-><c- o>>&amp;</c-> <c- n>a</c-><c- p>,</c->
                           <c- n>Real</c-><c- o>&amp;</c-> <c- n>c</c-><c- p>,</c->
                           <c- k>complex</c-><c- o>&lt;</c-><c- n>Real</c-><c- o>>&amp;</c-> <c- n>s</c-><c- p>,</c->
                           <c- k>complex</c-><c- o>&lt;</c-><c- n>Real</c-><c- o>>&amp;</c-> <c- n>r</c-><c- p>);</c->
</pre>
   <p>This function computes the plane (Givens) rotation represented by the
two values <code class="highlight"><c- n>c</c-></code> and <code class="highlight"><c- n>s</c-></code> such that the 2x2 system of equations</p>
<pre class="highlight"><c- p>[</c-><c- n>c</c->        <c- n>s</c-><c- p>]</c->   <c- p>[</c-><c- n>a</c-><c- p>]</c->   <c- p>[</c-><c- n>r</c-><c- p>]</c->
<c- p>[</c->          <c- p>]</c-> <c- o>*</c-> <c- p>[</c-> <c- p>]</c-> <c- o>=</c-> <c- p>[</c-> <c- p>]</c->
<c- p>[</c-><c- o>-</c-><c- n>conj</c-><c- p>(</c-><c- n>s</c-><c- p>)</c-> <c- n>c</c-><c- p>]</c->   <c- p>[</c-><c- n>b</c-><c- p>]</c->   <c- p>[</c-><c- mi>0</c-><c- p>]</c->
</pre>
   <p>holds, where <code class="highlight"><c- n>conj</c-></code> indicates the mathematical conjugate of <code class="highlight"><c- n>s</c-></code>, <code class="highlight"><c- n>c</c-></code> is always a real scalar, and <code class="highlight"><c- n>c</c-><c- o>*</c-><c- n>c</c-> <c- o>+</c-> <c- n>abs</c-><c- p>(</c-><c- n>s</c-><c- p>)</c-><c- o>*</c-><c- n>abs</c-><c- p>(</c-><c- n>s</c-><c- p>)</c-></code> equals one.  That
is, <code class="highlight"><c- n>c</c-></code> and <code class="highlight"><c- n>s</c-></code> represent a 2 x 2 matrix, that when multiplied by the
right by the input vector whose components are <code class="highlight"><c- n>a</c-></code> and <code class="highlight"><c- n>b</c-></code>, produces a
result vector whose first component <code class="highlight"><c- n>r</c-></code> is the Euclidean norm of the
input vector, and whose second component as zero. <em>[Note:</em> The C++
Standard Library <code class="highlight"><c- n>conj</c-></code> function always returns <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code> for some <code class="highlight"><c- n>T</c-></code>, even though overloads exist for non-complex input.  The above
expression uses <code class="highlight"><c- n>conj</c-></code> as mathematical notation, not as code.  --<em>end
note]</em></p>
   <p><em>[Note:</em> This function corresponds to the LAPACK function <code class="highlight"><c- n>xLARTG</c-></code>.
The BLAS variant <code class="highlight"><c- n>xROTG</c-></code> takes four arguments -- <code class="highlight"><c- n>a</c-></code>, <code class="highlight"><c- n>b</c-></code>, <code class="highlight"><c- n>c</c-></code>, and <code class="highlight"><c- n>s</c-></code>-- and overwrites the input <code class="highlight"><c- n>a</c-></code> with <code class="highlight"><c- n>r</c-></code>.  We have chosen <code class="highlight"><c- n>xLARTG</c-></code>'s interface because it separates input and output, and to
encourage following <code class="highlight"><c- n>xLARTG</c-></code>'s more careful implementation.  --<em>end note]</em></p>
   <p><em>[Note:</em> <code class="highlight"><c- n>givens_rotation_setup</c-></code> has an overload for complex numbers,
because the output argument <code class="highlight"><c- n>c</c-></code> (cosine) is a signed magnitude. --<em>end
note]</em></p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to <code class="highlight"><c- n>c</c-></code> and <code class="highlight"><c- n>s</c-></code> the plane (Givens) rotation
corresponding to the input <code class="highlight"><c- n>a</c-></code> and <code class="highlight"><c- n>b</c-></code>.  Assigns to <code class="highlight"><c- n>r</c-></code> the
Euclidean norm of the two-component vector formed by <code class="highlight"><c- n>a</c-></code> and <code class="highlight"><c- n>b</c-></code>.</p>
    <li data-md>
     <p><em>Throws:</em> Nothing.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.2.1.2" id="apply-a-computed-givens-rotation-to-vectors-linalgalgsblas1givensrot"><span class="secno">16.9.2.1.2. </span><span class="content">Apply a computed Givens rotation to vectors [linalg.algs.blas1.givens.rot]</span><a class="self-link" href="#apply-a-computed-givens-rotation-to-vectors-linalgalgsblas1givensrot"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>inout_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Real</c-><c- o>></c->
<c- b>void</c-> <c- n>givens_rotation_apply</c-><c- p>(</c->
  <c- n>inout_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- k>const</c-> <c- n>Real</c-> <c- n>c</c-><c- p>,</c->
  <c- k>const</c-> <c- n>Real</c-> <c- n>s</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Real</c-><c- o>></c->
<c- b>void</c-> <c- n>givens_rotation_apply</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>inout_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- k>const</c-> <c- n>Real</c-> <c- n>c</c-><c- p>,</c->
  <c- k>const</c-> <c- n>Real</c-> <c- n>s</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>inout_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Real</c-><c- o>></c->
<c- b>void</c-> <c- n>givens_rotation_apply</c-><c- p>(</c->
  <c- n>inout_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- k>const</c-> <c- n>Real</c-> <c- n>c</c-><c- p>,</c->
  <c- k>const</c-> <c- k>complex</c-><c- o>&lt;</c-><c- n>Real</c-><c- o>></c-> <c- n>s</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Real</c-><c- o>></c->
<c- b>void</c-> <c- n>givens_rotation_apply</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>inout_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- k>const</c-> <c- n>Real</c-> <c- n>c</c-><c- p>,</c->
  <c- k>const</c-> <c- k>complex</c-><c- o>&lt;</c-><c- n>Real</c-><c- o>></c-> <c- n>s</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em> These functions correspond to the BLAS function <code class="highlight"><c- n>xROT</c-></code>. <code class="highlight"><c- n>c</c-></code> and <code class="highlight"><c- n>s</c-></code> form a plane (Givens) rotation.  Users normally would compute <code class="highlight"><c- n>c</c-></code> and <code class="highlight"><c- n>s</c-></code> using <code class="highlight"><c- n>givens_rotation_setup</c-></code>, but they are not required to do
this.
--<em>end note]</em></p>
   <p>For the overloads that take the last argument <code class="highlight"><c- n>s</c-></code> as <code class="highlight"><c- n>Real</c-></code>,
for <code class="highlight"><c- n>i</c-></code> in the domains of both <code class="highlight"><c- n>x</c-></code> and <code class="highlight"><c- n>y</c-></code>,
the mathematical expressions for the algorithm are <code class="highlight"><c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-> <c- n>c</c-><c- o>*</c-><c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>+</c-> <c- n>s</c-><c- o>*</c-><c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code> and <code class="highlight"><c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-> <c- n>c</c-><c- o>*</c-><c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>-</c-> <c- n>s</c-><c- o>*</c-><c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code>.</p>
   <p>For the overloads that take the last argument <code class="highlight"><c- n>s</c-></code> as <code class="highlight"><c- k>const</c-> <c- n>complex</c-><c- o>&lt;</c-><c- n>Real</c-><c- o>></c-></code>,
for <code class="highlight"><c- n>i</c-></code> in the domains of both <code class="highlight"><c- n>x</c-></code> and <code class="highlight"><c- n>y</c-></code>,
the mathematical expressions for the algorithm are <code class="highlight"><c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-> <c- n>c</c-><c- o>*</c-><c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>+</c-> <c- n>s</c-><c- o>*</c-><c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code> and <code class="highlight"><c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-> <c- n>c</c-><c- o>*</c-><c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>-</c-> <c- n>conj</c-><c- p>(</c-><c- n>s</c-><c- p>)</c-><c- o>*</c-><c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Mandates:</em> If neither <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Effects:</em> Applies the plane (Givens) rotation specified by <code class="highlight"><c- n>c</c-></code> and <code class="highlight"><c- n>s</c-></code> to the input vectors <code class="highlight"><c- n>x</c-></code> and <code class="highlight"><c- n>y</c-></code>,
as if the rotation were a 2 x 2 matrix and
the input vectors were successive rows of a matrix with two rows.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.2.2" id="swap-matrix-or-vector-elements-linalgalgsblas1swap"><span class="secno">16.9.2.2. </span><span class="content">Swap matrix or vector elements [linalg.algs.blas1.swap]</span><a class="self-link" href="#swap-matrix-or-vector-elements-linalgalgsblas1swap"></a></h5>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>inout_object_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_object_2_t</c-><c- o>></c->
<c- b>void</c-> <c- n>swap_elements</c-><c- p>(</c-><c- n>inout_object_1_t</c-> <c- n>x</c-><c- p>,</c->
                   <c- n>inout_object_2_t</c-> <c- n>y</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_object_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_object_2_t</c-><c- o>></c->
<c- b>void</c-> <c- n>swap_elements</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                   <c- n>inout_object_1_t</c-> <c- n>x</c-><c- p>,</c->
                   <c- n>inout_object_2_t</c-> <c- n>y</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em> These functions correspond to the BLAS function <code class="highlight"><c- n>xSWAP</c-></code>.
--<em>end note]</em></p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> For all <code class="highlight"><c- n>r</c-></code> in 0, 1, ..., <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> - 1, <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code>.</p>
      <li data-md>
       <p><code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> is no more than 2.</p>
      <li data-md>
       <p>For <code class="highlight"><c- n>i</c-><c- p>...</c-></code> in the domain of <code class="highlight"><c- n>x</c-></code> and <code class="highlight"><c- n>y</c-></code>,
the expression <code class="highlight"><c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>...]</c-> <c- o>=</c-> <c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>...]</c-></code> is well formed.</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em> For all <code class="highlight"><c- n>r</c-></code> in 0, 1, ..., <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> - 1,
if neither <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>,
then <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Effects:</em> Swap all corresponding elements of the objects <code class="highlight"><c- n>x</c-></code> and <code class="highlight"><c- n>y</c-></code>.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.2.3" id="multiply-the-elements-of-an-object-in-place-by-a-scalar-linalgalgsblas1scal"><span class="secno">16.9.2.3. </span><span class="content">Multiply the elements of an object in place by a scalar [linalg.algs.blas1.scal]</span><a class="self-link" href="#multiply-the-elements-of-an-object-in-place-by-a-scalar-linalgalgsblas1scal"></a></h5>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Scalar</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_object_t</c-><c- o>></c->
<c- b>void</c-> <c- n>scale</c-><c- p>(</c-><c- k>const</c-> <c- n>Scalar</c-> <c- n>alpha</c-><c- p>,</c->
           <c- n>inout_object_t</c-> <c- n>obj</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Scalar</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_object_t</c-><c- o>></c->
<c- b>void</c-> <c- n>scale</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
           <c- k>const</c-> <c- n>Scalar</c-> <c- n>alpha</c-><c- p>,</c->
           <c- n>inout_object_t</c-> <c- n>obj</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em> These functions correspond to the BLAS function <code class="highlight"><c- n>xSCAL</c-></code>.
--<em>end note]</em></p>
   <p>For <code class="highlight"><c- n>i</c-><c- p>...</c-></code> in the domain of <code class="highlight"><c- n>obj</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>obj</c-><c- p>[</c-><c- n>i</c-><c- p>...]</c-> <c- o>=</c-> <c- n>alpha</c-> <c- o>*</c-> <c- n>obj</c-><c- p>[</c-><c- n>i</c-><c- p>...]</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Constraints:</em> <code class="highlight"><c- n>obj</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> is less than or equal to 2.</p>
    <li data-md>
     <p><em>Effects</em>: Replace each element of <code class="highlight"><c- n>obj</c-></code> in place
by the product of <code class="highlight"><c- n>alpha</c-></code> and that element.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.2.4" id="copy-elements-of-one-matrix-or-vector-into-another-linalgalgsblas1copy"><span class="secno">16.9.2.4. </span><span class="content">Copy elements of one matrix or vector into another [linalg.algs.blas1.copy]</span><a class="self-link" href="#copy-elements-of-one-matrix-or-vector-into-another-linalgalgsblas1copy"></a></h5>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_object_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_object_t</c-><c- o>></c->
<c- b>void</c-> <c- n>copy</c-><c- p>(</c-><c- n>in_object_t</c-> <c- n>x</c-><c- p>,</c->
          <c- n>out_object_t</c-> <c- n>y</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_object_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_object_t</c-><c- o>></c->
<c- b>void</c-> <c- n>copy</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
          <c- n>in_object_t</c-> <c- n>x</c-><c- p>,</c->
          <c- n>out_object_t</c-> <c- n>y</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em> These functions correspond to the BLAS function <code class="highlight"><c- n>xCOPY</c-></code>.
--<em>end note]</em></p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> For all <code class="highlight"><c- n>r</c-></code> in 0, 1, ..., <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> - 1, <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code>.</p>
      <li data-md>
       <p>For all <code class="highlight"><c- n>i</c-><c- p>...</c-></code> in the domain of <code class="highlight"><c- n>x</c-></code> and <code class="highlight"><c- n>y</c-></code>,
the expression <code class="highlight"><c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>...]</c-> <c- o>=</c-> <c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>...]</c-></code> is well formed.</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em> For all <code class="highlight"><c- n>r</c-></code> in 0, 1, ..., <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> - 1, if neither <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Effects:</em> Overwrite each element of <code class="highlight"><c- n>y</c-></code> with the corresponding
element of <code class="highlight"><c- n>x</c-></code>.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.2.5" id="add-vectors-or-matrices-elementwise-linalgalgsblas1add"><span class="secno">16.9.2.5. </span><span class="content">Add vectors or matrices elementwise [linalg.algs.blas1.add]</span><a class="self-link" href="#add-vectors-or-matrices-elementwise-linalgalgsblas1add"></a></h5>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_object_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_object_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_object_t</c-><c- o>></c->
<c- b>void</c-> <c- n>add</c-><c- p>(</c-><c- n>in_object_1_t</c-> <c- n>x</c-><c- p>,</c->
         <c- n>in_object_2_t</c-> <c- n>y</c-><c- p>,</c->
         <c- n>out_object_t</c-> <c- n>z</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_object_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_object_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_object_t</c-><c- o>></c->
<c- b>void</c-> <c- n>add</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
         <c- n>in_object_1_t</c-> <c- n>x</c-><c- p>,</c->
         <c- n>in_object_2_t</c-> <c- n>y</c-><c- p>,</c->
         <c- n>out_object_t</c-> <c- n>z</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em> These functions correspond to the BLAS function <code class="highlight"><c- n>xAXPY</c-></code>.
--<em>end note]</em></p>
   <p>For <code class="highlight"><c- n>i</c-><c- p>...</c-></code> in the domains of <code class="highlight"><c- n>x</c-></code>, <code class="highlight"><c- n>y</c-></code>, and <code class="highlight"><c- n>z</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>z</c-><c- p>[</c-><c- n>i</c-><c- p>...]</c-> <c- o>=</c-> <c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>...]</c-> <c- o>+</c-> <c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>...]</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> For all <code class="highlight"><c- n>r</c-></code> in 0, 1, ..., <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> - 1,</p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p><code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Constraints:</em> <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code>, <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code>, and <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> are all equal.</p>
    <li data-md>
     <p><em>Mandates:</em> For all <code class="highlight"><c- n>r</c-></code> in 0, 1, ..., <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> - 1,</p>
     <ul>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code>; and</p>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code>;</p>
     </ul>
    <li data-md>
     <p><em>Effects</em>: Compute the elementwise sum z = x + y.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.2.6" id="dot-product-of-two-vectors-linalgalgsblas1dot"><span class="secno">16.9.2.6. </span><span class="content">Dot product of two vectors [linalg.algs.blas1.dot]</span><a class="self-link" href="#dot-product-of-two-vectors-linalgalgsblas1dot"></a></h5>
   <h6 class="heading settled" data-level="16.9.2.6.1" id="nonconjugated-dot-product-of-two-vectors-linalgalgsblas1dotdotu"><span class="secno">16.9.2.6.1. </span><span class="content">Nonconjugated dot product of two vectors [linalg.algs.blas1.dot.dotu]</span><a class="self-link" href="#nonconjugated-dot-product-of-two-vectors-linalgalgsblas1dotdotu"></a></h6>
   <p><em>[Note:</em> The functions in this section correspond to the BLAS
functions <code class="highlight"><c- n>xDOT</c-></code> (for real element types) and <code class="highlight"><c- n>xDOTU</c-></code> (for complex
element types).  --<em>end note]</em></p>
   <p>Nonconjugated dot product with specified result type</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>dot</c-><c- p>(</c-><c- n>in_vector_1_t</c-> <c- n>v1</c-><c- p>,</c->
      <c- n>in_vector_2_t</c-> <c- n>v2</c-><c- p>,</c->
      <c- n>T</c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>dot</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
      <c- n>in_vector_1_t</c-> <c- n>v1</c-><c- p>,</c->
      <c- n>in_vector_2_t</c-> <c- n>v2</c-><c- p>,</c->
      <c- n>T</c-> <c- n>init</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>N</c-></code> equal to <code class="highlight"><c- n>v1</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>init</c-> <c- o>=</c-> <c- n>init</c-></code> plus the sum of <code class="highlight"><c- n>v1</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>*</c-> <c- n>v2</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>i</c-></code> in the domain of <code class="highlight"><c- n>v1</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> <code class="highlight"><c- n>v1</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>v2</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Mandates:</em> If neither <code class="highlight"><c- n>v1</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>v2</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>v1</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>v2</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Effects:</em> Let <code class="highlight"><c- n>N</c-></code> be <code class="highlight"><c- n>v1</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.
If <code class="highlight"><c- n>N</c-></code> is zero, returns <code class="highlight"><c- n>init</c-></code>, else returns <em>GENERALIZED_SUM</em>(<code class="highlight"><c- n>plus</c-><c- o>&lt;></c-><c- p>()</c-></code>, <code class="highlight"><c- n>init</c-></code>, <code class="highlight"><c- n>v1</c-><c- p>[</c-><c- mi>0</c-><c- p>]</c-><c- o>*</c-><c- n>v2</c-><c- p>[</c-><c- mi>0</c-><c- p>]</c-></code>, ..., <code class="highlight"><c- n>v1</c-><c- p>[</c-><c- n>N</c-><c- mi>-1</c-><c- p>]</c-><c- o>*</c-><c- n>v2</c-><c- p>[</c-><c- n>N</c-><c- mi>-1</c-><c- p>]</c-></code>).</p>
    <li data-md>
     <p><em>Remarks:</em> If <code class="highlight"><c- n>in_vector_t</c-><c- o>::</c-><c- n>element_type</c-></code> and <code class="highlight"><c- n>T</c-></code> are both
floating-point types or complex versions thereof, and if <code class="highlight"><c- n>T</c-></code> has
higher precision than <code class="highlight"><c- n>in_vector_type</c-><c- o>::</c-><c- n>element_type</c-></code>, then
intermediate terms in the sum use <code class="highlight"><c- n>T</c-></code>'s precision or greater.</p>
   </ul>
   <p><em>[Note:</em> Like <code class="highlight"><c- n>reduce</c-></code>, <code class="highlight"><c- n>dot</c-></code> applies binary <code class="highlight"><c- k>operator</c-><c- o>+</c-></code> in an
unspecified order.  This may yield a nondeterministic result for
non-associative or non-commutative <code class="highlight"><c- k>operator</c-><c- o>+</c-></code> such as floating-point
addition.  However, implementations may perform extra work to make the
result deterministic.  They may do so for all <code class="highlight"><c- n>dot</c-></code> overloads, or just
for specific <code class="highlight"><c- n>ExecutionPolicy</c-></code> types. --<em>end note]</em></p>
   <p><em>[Note:</em> Users can get <code class="highlight"><c- n>xDOTC</c-></code> behavior by giving the first argument
as the result of <code class="highlight"><c- n>conjugated</c-></code>.  Alternately, they can use the shortcut <code class="highlight"><c- n>dotc</c-></code> below. --<em>end note]</em></p>
   <p>Nonconjugated dot product with default result type</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>dot</c-><c- p>(</c-><c- n>in_vector_1_t</c-> <c- n>v1</c-><c- p>,</c->
         <c- n>in_vector_2_t</c-> <c- n>v2</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>dot</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
         <c- n>in_vector_1_t</c-> <c- n>v1</c-><c- p>,</c->
         <c- n>in_vector_2_t</c-> <c- n>v2</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Let <code class="highlight"><c- n>T</c-></code> be <code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>v1</c-><c- p>[</c-><c- mi>0</c-><c- p>]</c-><c- o>*</c-><c- n>v2</c-><c- p>[</c-><c- mi>0</c-><c- p>])</c-></code>.  Then, the
two-parameter overload is equivalent to <code class="highlight"><c- n>dot</c-><c- p>(</c-><c- n>v1</c-><c- p>,</c-> <c- n>v2</c-><c- p>,</c-> <c- n>T</c-><c- p>{});</c-></code>, and the
three-parameter overload is equivalent to <code class="highlight"><c- n>dot</c-><c- p>(</c-><c- n>exec</c-><c- p>,</c-> <c- n>v1</c-><c- p>,</c-> <c- n>v2</c-><c- p>,</c-> <c- n>T</c-><c- p>{});</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.2.6.2" id="conjugated-dot-product-of-two-vectors-linalgalgsblas1dotdotc"><span class="secno">16.9.2.6.2. </span><span class="content">Conjugated dot product of two vectors [linalg.algs.blas1.dot.dotc]</span><a class="self-link" href="#conjugated-dot-product-of-two-vectors-linalgalgsblas1dotdotc"></a></h6>
   <p><em>[Note:</em></p>
   <p>The functions in this section correspond to the BLAS functions <code class="highlight"><c- n>xDOT</c-></code> (for real element types) and <code class="highlight"><c- n>xDOTC</c-></code> (for complex element types).</p>
   <p><code class="highlight"><c- n>dotc</c-></code> exists to give users reasonable default inner product behavior
for both real and complex element types.</p>
   <p>--<em>end note]</em></p>
   <p>Conjugated dot product with specified result type</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>dotc</c-><c- p>(</c-><c- n>in_vector_1_t</c-> <c- n>v1</c-><c- p>,</c->
       <c- n>in_vector_2_t</c-> <c- n>v2</c-><c- p>,</c->
       <c- n>T</c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>dotc</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
       <c- n>in_vector_1_t</c-> <c- n>v1</c-><c- p>,</c->
       <c- n>in_vector_2_t</c-> <c- n>v2</c-><c- p>,</c->
       <c- n>T</c-> <c- n>init</c-><c- p>);</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> The three-argument overload is equivalent to <code class="highlight"><c- n>dot</c-><c- p>(</c-><c- n>conjugated</c-><c- p>(</c-><c- n>v1</c-><c- p>),</c-> <c- n>v2</c-><c- p>,</c-> <c- n>init</c-><c- p>);</c-></code>.
The four-argument overload is equivalent to <code class="highlight"><c- n>dot</c-><c- p>(</c-><c- n>exec</c-><c- p>,</c-> <c- n>conjugated</c-><c- p>(</c-><c- n>v1</c-><c- p>),</c-> <c- n>v2</c-><c- p>,</c-> <c- n>init</c-><c- p>);</c-></code>.</p>
   </ul>
   <p>Conjugated dot product with default result type</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>dotc</c-><c- p>(</c-><c- n>in_vector_1_t</c-> <c- n>v1</c-><c- p>,</c->
          <c- n>in_vector_2_t</c-> <c- n>v2</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>dotc</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
          <c- n>in_vector_1_t</c-> <c- n>v1</c-><c- p>,</c->
          <c- n>in_vector_2_t</c-> <c- n>v2</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> If <code class="highlight"><c- n>in_vector_1_t</c-><c- o>::</c-><c- n>element_type</c-></code> is <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- n>R</c-><c- o>></c-></code> for some <code class="highlight"><c- n>R</c-></code>, let <code class="highlight"><c- n>T</c-></code> be <code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>conj</c-><c- p>(</c-><c- n>v1</c-><c- p>[</c-><c- mi>0</c-><c- p>])</c-><c- o>*</c-><c- n>v2</c-><c- p>[</c-><c- mi>0</c-><c- p>])</c-></code>; else, let <code class="highlight"><c- n>T</c-></code> be <code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>v1</c-><c- p>[</c-><c- mi>0</c-><c- p>]</c-><c- o>*</c-><c- n>v2</c-><c- p>[</c-><c- mi>0</c-><c- p>])</c-></code>.  Then, the two-parameter overload is
equivalent to <code class="highlight"><c- n>dotc</c-><c- p>(</c-><c- n>v1</c-><c- p>,</c-> <c- n>v2</c-><c- p>,</c-> <c- n>T</c-><c- p>{});</c-></code>, and the three-parameter overload
is equivalent to <code class="highlight"><c- n>dotc</c-><c- p>(</c-><c- n>exec</c-><c- p>,</c-> <c- n>v1</c-><c- p>,</c-> <c- n>v2</c-><c- p>,</c-> <c- n>T</c-><c- p>{});</c-></code>.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.2.7" id="scaled-sum-of-squares-of-a-vectors-elements-linalgalgsblas1ssq"><span class="secno">16.9.2.7. </span><span class="content">Scaled sum of squares of a vector’s elements [linalg.algs.blas1.ssq]</span><a class="self-link" href="#scaled-sum-of-squares-of-a-vectors-elements-linalgalgsblas1ssq"></a></h5>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- k>struct</c-> <c- nc>sum_of_squares_result</c-> <c- p>{</c->
  <c- n>T</c-> <c- n>scaling_factor</c-><c- p>;</c->
  <c- n>T</c-> <c- n>scaled_sum_of_squares</c-><c- p>;</c->
<c- p>};</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>sum_of_squares_result</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- n>vector_sum_of_squares</c-><c- p>(</c->
  <c- n>in_vector_t</c-> <c- n>v</c-><c- p>,</c->
  <c- n>sum_of_squares_result</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>sum_of_squares_result</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- n>vector_sum_of_squares</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>v</c-><c- p>,</c->
  <c- n>sum_of_squares_result</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- n>init</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em> These functions correspond to the LAPACK function <code class="highlight"><c- n>xLASSQ</c-></code>.
--<em>end note]</em></p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>T</c-></code> shall be <em>Cpp17MoveConstructible</em> and <em>Cpp17LessThanComparable</em>, and</p>
      <li data-md>
       <p><code class="highlight"><c- n>abs</c-><c- p>(</c-><c- n>x</c-><c- p>[</c-><c- mi>0</c-><c- p>])</c-></code> shall be convertible to <code class="highlight"><c- n>T</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Constraints:</em> For all <code class="highlight"><c- n>i</c-></code> in the domain of <code class="highlight"><c- n>v</c-></code>,
and for <code class="highlight"><c- n>f</c-></code> and <code class="highlight"><c- n>ssq</c-></code> of type <code class="highlight"><c- n>T</c-></code>,
the expression <code class="highlight"><c- n>ssq</c-> <c- o>=</c-> <c- n>ssq</c-> <c- o>+</c-> <c- p>(</c-><c- n>abs</c-><c- p>(</c-><c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>])</c-> <c- o>/</c-> <c- n>f</c-><c- p>)</c-><c- o>*</c-><c- p>(</c-><c- n>abs</c-><c- p>(</c-><c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>])</c-> <c- o>/</c-> <c- n>f</c-><c- p>)</c-></code> is well formed.</p>
    <li data-md>
     <p><em>Effects:</em> Returns two values:</p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>scaling_factor</c-></code>: the maximum of <code class="highlight"><c- n>init</c-><c- p>.</c-><c- n>scaling_factor</c-></code> and <code class="highlight"><c- n>abs</c-><c- p>(</c-><c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>])</c-></code> for all <code class="highlight"><c- n>i</c-></code> in the domain of <code class="highlight"><c- n>v</c-></code>; and</p>
      <li data-md>
       <p><code class="highlight"><c- n>scaled_sum_of_squares</c-></code>: a value such that <code class="highlight"><c- n>scaling_factor</c-> <c- o>*</c-> <c- n>scaling_factor</c-> <c- o>*</c-> <c- n>scaled_sum_of_squares</c-></code> equals the sum of squares of <code class="highlight"><c- n>abs</c-><c- p>(</c-><c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>])</c-></code> plus <code class="highlight"><c- n>init</c-><c- p>.</c-><c- n>scaling_factor</c-> <c- o>*</c-> <c- n>init</c-><c- p>.</c-><c- n>scaling_factor</c-> <c- o>*</c-> <c- n>init</c-><c- p>.</c-><c- n>scaled_sum_of_squares</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Remarks:</em> If <code class="highlight"><c- n>in_vector_t</c-><c- o>::</c-><c- n>element_type</c-></code> is either a floating-point type
or <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- n>R</c-><c- o>></c-></code> for some floating-point type <code class="highlight"><c- n>R</c-></code>,
and if <code class="highlight"><c- n>T</c-></code> is a floating-point type, then</p>
     <ul>
      <li data-md>
       <p>if <code class="highlight"><c- n>T</c-></code> has higher precision than <code class="highlight"><c- n>in_vector_type</c-><c- o>::</c-><c- n>element_type</c-></code>, then
intermediate terms in the sum use <code class="highlight"><c- n>T</c-></code>'s precision or greater; and</p>
      <li data-md>
       <p>any guarantees regarding overflow and underflow of <code class="highlight"><c- n>vector_sum_of_squares</c-></code> are implementation-defined.</p>
     </ul>
   </ul>
   <h5 class="heading settled" data-level="16.9.2.8" id="euclidean-norm-of-a-vector-linalgalgsblas1nrm2"><span class="secno">16.9.2.8. </span><span class="content">Euclidean norm of a vector [linalg.algs.blas1.nrm2]</span><a class="self-link" href="#euclidean-norm-of-a-vector-linalgalgsblas1nrm2"></a></h5>
   <h6 class="heading settled" data-level="16.9.2.8.1" id="euclidean-norm-with-specified-result-type"><span class="secno">16.9.2.8.1. </span><span class="content">Euclidean norm with specified result type</span><a class="self-link" href="#euclidean-norm-with-specified-result-type"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>vector_norm2</c-><c- p>(</c-><c- n>in_vector_t</c-> <c- n>v</c-><c- p>,</c->
               <c- n>T</c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>vector_norm2</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
               <c- n>in_vector_t</c-> <c- n>v</c-><c- p>,</c->
               <c- n>T</c-> <c- n>init</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em> These functions correspond to the BLAS function <code class="highlight"><c- n>xNRM2</c-></code>.
--<em>end note]</em></p>
   <p>For <code class="highlight"><c- n>N</c-></code> equal to <code class="highlight"><c- n>v</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>sqrt</c-><c- p>(</c-><c- n>init</c-> <c- o>+</c-> <c- n>s</c-><c- p>)</c-></code>,
where <code class="highlight"><c- n>s</c-></code> is the sum of <code class="highlight"><c- n>abs</c-><c- p>(</c-><c- n>v</c-><c- p>[</c-><c- n>i</c-><c- p>])</c-> <c- o>*</c-> <c- n>abs</c-><c- p>(</c-><c- n>v</c-><c- p>[</c-><c- n>i</c-><c- p>])</c-></code> for all <code class="highlight"><c- n>i</c-></code> in the domain of <code class="highlight"><c- n>v</c-></code>. <em>[Note:</em> This does not imply a recommended implementation for floating-point types.
See <em>Remarks</em> below.
--<em>end note]</em></p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> <code class="highlight"><c- n>init</c-> <c- o>+</c-> <c- n>abs</c-><c- p>(</c-><c- n>v</c-><c- p>[</c-><c- mi>0</c-><c- p>])</c-><c- o>*</c-><c- n>abs</c-><c- p>(</c-><c- n>v</c-><c- p>[</c-><c- mi>0</c-><c- p>])</c-></code> shall be convertible to <code class="highlight"><c- n>T</c-></code>.</p>
    <li data-md>
     <p><em>Effects:</em> Returns the Euclidean norm (also called 2-norm)
of the vector <code class="highlight"><c- n>v</c-></code>.</p>
    <li data-md>
     <p><em>Remarks:</em> If <code class="highlight"><c- n>in_vector_t</c-><c- o>::</c-><c- n>element_type</c-></code> is a floating-point type
or a complex version thereof, and if <code class="highlight"><c- n>T</c-></code> is a floating-point type, then</p>
     <ul>
      <li data-md>
       <p>if <code class="highlight"><c- n>T</c-></code> has higher precision than <code class="highlight"><c- n>in_vector_type</c-><c- o>::</c-><c- n>element_type</c-></code>, then
intermediate terms in the sum use <code class="highlight"><c- n>T</c-></code>'s precision or greater; and</p>
      <li data-md>
       <p>any guarantees regarding overflow and underflow of <code class="highlight"><c- n>vector_norm2</c-></code> are implementation-defined.</p>
     </ul>
   </ul>
   <p><em>[Note:</em> A suggested implementation of this function for floating-point types <code class="highlight"><c- n>T</c-></code> would use the <code class="highlight"><c- n>scaled_sum_of_squares</c-></code> result
from <code class="highlight"><c- n>vector_sum_of_squares</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- p>{</c-><c- mf>0.0</c-><c- p>,</c-> <c- mf>1.0</c-><c- p>})</c-></code>.
--<em>end note]</em></p>
   <h6 class="heading settled" data-level="16.9.2.8.2" id="euclidean-norm-with-default-result-type"><span class="secno">16.9.2.8.2. </span><span class="content">Euclidean norm with default result type</span><a class="self-link" href="#euclidean-norm-with-default-result-type"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>vector_norm2</c-><c- p>(</c-><c- n>in_vector_t</c-> <c- n>v</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>vector_norm2</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                  <c- n>in_vector_t</c-> <c- n>v</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Let <code class="highlight"><c- n>T</c-></code> be <code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>abs</c-><c- p>(</c-><c- n>v</c-><c- p>[</c-><c- mi>0</c-><c- p>])</c-> <c- o>*</c-> <c- n>abs</c-><c- p>(</c-><c- n>v</c-><c- p>[</c-><c- mi>0</c-><c- p>]))</c-></code>.
Then, the one-parameter overload is equivalent to <code class="highlight"><c- n>vector_norm2</c-><c- p>(</c-><c- n>v</c-><c- p>,</c-> <c- n>T</c-><c- p>{});</c-></code>,
and the two-parameter overload is equivalent to <code class="highlight"><c- n>vector_norm2</c-><c- p>(</c-><c- n>exec</c-><c- p>,</c-> <c- n>v</c-><c- p>,</c-> <c- n>T</c-><c- p>{});</c-></code>.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.2.9" id="sum-of-absolute-values-of-vector-elements-linalgalgsblas1asum"><span class="secno">16.9.2.9. </span><span class="content">Sum of absolute values of vector elements [linalg.algs.blas1.asum]</span><a class="self-link" href="#sum-of-absolute-values-of-vector-elements-linalgalgsblas1asum"></a></h5>
   <h6 class="heading settled" data-level="16.9.2.9.1" id="sum-of-absolute-values-with-specified-result-type"><span class="secno">16.9.2.9.1. </span><span class="content">Sum of absolute values with specified result type</span><a class="self-link" href="#sum-of-absolute-values-with-specified-result-type"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>vector_abs_sum</c-><c- p>(</c-><c- n>in_vector_t</c-> <c- n>v</c-><c- p>,</c->
                 <c- n>T</c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>vector_abs_sum</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                 <c- n>in_vector_t</c-> <c- n>v</c-><c- p>,</c->
                 <c- n>T</c-> <c- n>init</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em> This function corresponds to the BLAS functions <code class="highlight"><c- n>SASUM</c-></code>, <code class="highlight"><c- n>DASUM</c-></code>, <code class="highlight"><c- n>CSASUM</c-></code>, and <code class="highlight"><c- n>DZASUM</c-></code>.  The different behavior for complex
element types is based on the observation that this lower-cost
approximation of the one-norm serves just as well as the actual
one-norm for many linear algebra algorithms in practice. --<em>end note]</em></p>
   <p>For <code class="highlight"><c- n>N</c-></code> equal to <code class="highlight"><c- n>v</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>init</c-></code> plus the sum of <code class="highlight"><c- n>abs</c-><c- p>(</c-><c- n>v</c-><c- p>[</c-><c- n>i</c-><c- p>])</c-></code> for all <code class="highlight"><c- n>i</c-></code> in the domain of <code class="highlight"><c- n>v</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> For <code class="highlight"><c- n>i</c-></code> in the domain of <code class="highlight"><c- n>v</c-></code>, <code class="highlight"><c- n>init</c-> <c- o>+</c-> <c- n>abs</c-><c- p>(</c-><c- n>v</c-><c- p>[</c-><c- n>i</c-><c- p>])</c-></code> shall be convertible to <code class="highlight"><c- n>T</c-></code>.</p>
    <li data-md>
     <p><em>Effects:</em> Let <code class="highlight"><c- n>N</c-></code> be <code class="highlight"><c- n>v</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>:</p>
     <ul>
      <li data-md>
       <p>If <code class="highlight"><c- n>N</c-></code> is zero, returns <code class="highlight"><c- n>init</c-></code>;</p>
      <li data-md>
       <p>else, if <code class="highlight"><c- n>in_vector_t</c-><c- o>::</c-><c- n>element_type</c-></code> is <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- n>R</c-><c- o>></c-></code> for some <code class="highlight"><c- n>R</c-></code>,
then returns <em>GENERALIZED_SUM</em>(<code class="highlight"><c- n>plus</c-><c- o>&lt;></c-><c- p>()</c-></code>, <code class="highlight"><c- n>init</c-></code>, <code class="highlight"><c- n>abs</c-><c- p>(</c-><c- n>real</c-><c- p>(</c-><c- n>v</c-><c- p>[</c-><c- mi>0</c-><c- p>]))</c-> <c- o>+</c-> <c- n>abs</c-><c- p>(</c-><c- n>imag</c-><c- p>(</c-><c- n>v</c-><c- p>[</c-><c- mi>0</c-><c- p>]))</c-></code>, ..., <code class="highlight"><c- n>abs</c-><c- p>(</c-><c- n>real</c-><c- p>(</c-><c- n>v</c-><c- p>[</c-><c- n>N</c-><c- mi>-1</c-><c- p>]))</c-> <c- o>+</c-> <c- n>abs</c-><c- p>(</c-><c- n>imag</c-><c- p>(</c-><c- n>v</c-><c- p>[</c-><c- n>N</c-><c- mi>-1</c-><c- p>]))</c-></code>).</p>
      <li data-md>
       <p>else, returns <em>GENERALIZED_SUM</em>(<code class="highlight"><c- n>plus</c-><c- o>&lt;></c-><c- p>()</c-></code>, <code class="highlight"><c- n>init</c-></code>, <code class="highlight"><c- n>abs</c-><c- p>(</c-><c- n>v</c-><c- p>[</c-><c- mi>0</c-><c- p>])</c-></code>, ..., <code class="highlight"><c- n>abs</c-><c- p>(</c-><c- n>v</c-><c- p>[</c-><c- n>N</c-><c- mi>-1</c-><c- p>])</c-></code>).</p>
     </ul>
    <li data-md>
     <p><em>Remarks:</em> If <code class="highlight"><c- n>in_vector_t</c-><c- o>::</c-><c- n>element_type</c-></code> is a floating-point type
or a complex version thereof, if <code class="highlight"><c- n>T</c-></code> is a floating-point type,
and if <code class="highlight"><c- n>T</c-></code> has higher precision than <code class="highlight"><c- n>in_vector_type</c-><c- o>::</c-><c- n>element_type</c-></code>,
then intermediate terms in the sum use <code class="highlight"><c- n>T</c-></code>'s precision or greater.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.2.9.2" id="sum-of-absolute-values-with-default-result-type"><span class="secno">16.9.2.9.2. </span><span class="content">Sum of absolute values with default result type</span><a class="self-link" href="#sum-of-absolute-values-with-default-result-type"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>vector_abs_sum</c-><c- p>(</c-><c- n>in_vector_t</c-> <c- n>v</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>vector_abs_sum</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                    <c- n>in_vector_t</c-> <c- n>v</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Let <code class="highlight"><c- n>T</c-></code> be <code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>abs</c-><c- p>(</c-><c- n>v</c-><c- p>[</c-><c- mi>0</c-><c- p>]))</c-></code>.  Then, the
one-parameter overload is equivalent to <code class="highlight"><c- n>vector_abs_sum</c-><c- p>(</c-><c- n>v</c-><c- p>,</c-> <c- n>T</c-><c- p>{});</c-></code>,
and the two-parameter overload is equivalent to <code class="highlight"><c- n>vector_abs_sum</c-><c- p>(</c-><c- n>exec</c-><c- p>,</c-> <c- n>v</c-><c- p>,</c-> <c- n>T</c-><c- p>{});</c-></code>.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.2.10" id="index-of-maximum-absolute-value-of-vector-elements-linalgalgsblas1iamax"><span class="secno">16.9.2.10. </span><span class="content">Index of maximum absolute value of vector elements [linalg.algs.blas1.iamax]</span><a class="self-link" href="#index-of-maximum-absolute-value-of-vector-elements-linalgalgsblas1iamax"></a></h5>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_t</c-><c- o>></c->
<c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>idx_abs_max</c-><c- p>(</c-><c- n>in_vector_t</c-> <c- n>v</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- o>></c->
<c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>idx_abs_max</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>v</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em> These functions correspond to the BLAS function <code class="highlight"><c- n>IxAMAX</c-></code>.
--<em>end note]</em></p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> For <code class="highlight"><c- n>i</c-></code> in the domain of <code class="highlight"><c- n>v</c-></code>,
let <code class="highlight"><c- n>abs_value_type</c-></code> be <code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>v</c-><c- p>[</c-><c- n>i</c-><c- p>])</c-></code>;
then, <code class="highlight"><c- n>abs_value_type</c-></code> shall be <em>Cpp17LessThanComparable</em>.</p>
    <li data-md>
     <p><em>Effects:</em> Returns the index (in the domain of <code class="highlight"><c- n>v</c-></code>) of
the first element of <code class="highlight"><c- n>v</c-></code> having largest absolute value.  If <code class="highlight"><c- n>v</c-></code> has
zero elements, then returns <code class="highlight"><c- n>numeric_limits</c-><c- o>&lt;</c-><c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-><c- o>>::</c-><c- n>max</c-><c- p>()</c-></code>.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.2.11" id="frobenius-norm-of-a-matrix-linalgalgsblas1matfrobnorm"><span class="secno">16.9.2.11. </span><span class="content">Frobenius norm of a matrix [linalg.algs.blas1.matfrobnorm]</span><a class="self-link" href="#frobenius-norm-of-a-matrix-linalgalgsblas1matfrobnorm"></a></h5>
   <h6 class="heading settled" data-level="16.9.2.11.1" id="frobenius-norm-with-specified-result-type"><span class="secno">16.9.2.11.1. </span><span class="content">Frobenius norm with specified result type</span><a class="self-link" href="#frobenius-norm-with-specified-result-type"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>matrix_frob_norm</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>T</c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>matrix_frob_norm</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>T</c-> <c- n>init</c-><c- p>);</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Returns the Frobenius norm of the matrix <code class="highlight"><c- n>A</c-></code>, that is,
the square root of the sum of squares
of the absolute values of the elements of <code class="highlight"><c- n>A</c-></code>. <em>[Note:</em> This does not imply a recommended implementation for floating-point types.
See <em>Remarks</em> below.
--<em>end note]</em></p>
    <li data-md>
     <p><em>Remarks:</em> If <code class="highlight"><c- n>in_matrix_t</c-><c- o>::</c-><c- n>element_type</c-></code> is a floating-point type
or <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- n>R</c-><c- o>></c-></code> for some floating-point type <code class="highlight"><c- n>R</c-></code>,
and if <code class="highlight"><c- n>T</c-></code> is a floating-point type, then</p>
     <ul>
      <li data-md>
       <p>if <code class="highlight"><c- n>T</c-></code> has higher precision than <code class="highlight"><c- n>in_matrix_type</c-><c- o>::</c-><c- n>element_type</c-></code>, then
intermediate terms in the sum use <code class="highlight"><c- n>T</c-></code>'s precision or greater; and</p>
      <li data-md>
       <p>any guarantees regarding overflow and underflow of <code class="highlight"><c- n>matrix_frob_norm</c-></code> are implementation-defined.</p>
     </ul>
   </ul>
   <h6 class="heading settled" data-level="16.9.2.11.2" id="frobenius-norm-with-default-result-type"><span class="secno">16.9.2.11.2. </span><span class="content">Frobenius norm with default result type</span><a class="self-link" href="#frobenius-norm-with-default-result-type"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>matrix_frob_norm</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>matrix_frob_norm</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Let <code class="highlight"><c- n>T</c-></code> be <code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>abs</c-><c- p>(</c-><c- n>A</c-><c- p>[</c-><c- mi>0</c-><c- p>,</c-><c- mi>0</c-><c- p>])</c-> <c- o>*</c-> <c- n>abs</c-><c- p>(</c-><c- n>A</c-><c- p>[</c-><c- mi>0</c-><c- p>,</c-><c- mi>0</c-><c- p>]))</c-></code>.
Then, the one-parameter overload is equivalent to <code class="highlight"><c- n>matrix_frob_norm</c-><c- p>(</c-><c- n>A</c-><c- p>,</c-> <c- n>T</c-><c- p>{});</c-></code>,
and the two-parameter overload is equivalent to <code class="highlight"><c- n>matrix_frob_norm</c-><c- p>(</c-><c- n>exec</c-><c- p>,</c-> <c- n>A</c-><c- p>,</c-> <c- n>T</c-><c- p>{});</c-></code>.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.2.12" id="one-norm-of-a-matrix-linalgalgsblas1matonenorm"><span class="secno">16.9.2.12. </span><span class="content">One norm of a matrix [linalg.algs.blas1.matonenorm]</span><a class="self-link" href="#one-norm-of-a-matrix-linalgalgsblas1matonenorm"></a></h5>
   <h6 class="heading settled" data-level="16.9.2.12.1" id="one-norm-with-specified-result-type"><span class="secno">16.9.2.12.1. </span><span class="content">One norm with specified result type</span><a class="self-link" href="#one-norm-with-specified-result-type"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>matrix_one_norm</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>T</c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>matrix_one_norm</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>T</c-> <c- n>init</c-><c- p>);</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> <code class="highlight"><c- n>abs</c-><c- p>(</c-><c- n>A</c-><c- p>[</c-><c- mi>0</c-><c- p>,</c-><c- mi>0</c-><c- p>])</c-></code> shall be convertible to <code class="highlight"><c- n>T</c-></code>.</p>
    <li data-md>
     <p><em>Effects:</em></p>
     <ul>
      <li data-md>
       <p>If <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> is zero, returns <code class="highlight"><c- n>init</c-></code>;</p>
      <li data-md>
       <p>else, returns the sum of <code class="highlight"><c- n>init</c-></code> and the one norm of the matrix <code class="highlight"><c- n>A</c-></code>.
The one norm of the matrix <code class="highlight"><c- n>A</c-></code> is the maximum over all columns of <code class="highlight"><c- n>A</c-></code>,
of the sum of the absolute values of the elements of the column.</p>
     </ul>
    <li data-md>
     <p><em>Remarks:</em> If <code class="highlight"><c- n>in_matrix_t</c-><c- o>::</c-><c- n>element_type</c-></code> is a floating-point type
or <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- n>R</c-><c- o>></c-></code> for some floating-point type <code class="highlight"><c- n>R</c-></code>,
if <code class="highlight"><c- n>T</c-></code> is a floating-point type,
and if <code class="highlight"><c- n>T</c-></code> has higher precision than <code class="highlight"><c- n>in_matrix_type</c-><c- o>::</c-><c- n>element_type</c-></code>,
then intermediate terms in each sum use <code class="highlight"><c- n>T</c-></code>'s precision or greater.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.2.12.2" id="one-norm-with-default-result-type"><span class="secno">16.9.2.12.2. </span><span class="content">One norm with default result type</span><a class="self-link" href="#one-norm-with-default-result-type"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>matrix_one_norm</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>matrix_one_norm</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Let <code class="highlight"><c- n>T</c-></code> be <code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>abs</c-><c- p>(</c-><c- n>A</c-><c- p>[</c-><c- mi>0</c-><c- p>,</c-><c- mi>0</c-><c- p>])</c-></code>.
Then, the one-parameter overload is equivalent to <code class="highlight"><c- n>matrix_one_norm</c-><c- p>(</c-><c- n>A</c-><c- p>,</c-> <c- n>T</c-><c- p>{});</c-></code>,
and the two-parameter overload is equivalent to <code class="highlight"><c- n>matrix_one_norm</c-><c- p>(</c-><c- n>exec</c-><c- p>,</c-> <c- n>A</c-><c- p>,</c-> <c- n>T</c-><c- p>{});</c-></code>.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.2.13" id="infinity-norm-of-a-matrix-linalgalgsblas1matinfnorm"><span class="secno">16.9.2.13. </span><span class="content">Infinity norm of a matrix [linalg.algs.blas1.matinfnorm]</span><a class="self-link" href="#infinity-norm-of-a-matrix-linalgalgsblas1matinfnorm"></a></h5>
   <h6 class="heading settled" data-level="16.9.2.13.1" id="infinity-norm-with-specified-result-type"><span class="secno">16.9.2.13.1. </span><span class="content">Infinity norm with specified result type</span><a class="self-link" href="#infinity-norm-with-specified-result-type"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>matrix_inf_norm</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>T</c-> <c- n>init</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>matrix_inf_norm</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>T</c-> <c- n>init</c-><c- p>);</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> <code class="highlight"><c- n>abs</c-><c- p>(</c-><c- n>A</c-><c- p>[</c-><c- mi>0</c-><c- p>,</c-><c- mi>0</c-><c- p>])</c-></code> shall be convertible to <code class="highlight"><c- n>T</c-></code>.</p>
    <li data-md>
     <p><em>Effects:</em></p>
     <ul>
      <li data-md>
       <p>If <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> is zero, returns <code class="highlight"><c- n>init</c-></code>;</p>
      <li data-md>
       <p>else, returns the sum of <code class="highlight"><c- n>init</c-></code> and the infinity norm of the matrix <code class="highlight"><c- n>A</c-></code>.
The infinity norm of the matrix <code class="highlight"><c- n>A</c-></code> is the maximum over all rows of <code class="highlight"><c- n>A</c-></code>,
of the sum of the absolute values of the elements of the row.</p>
     </ul>
    <li data-md>
     <p><em>Remarks:</em> If <code class="highlight"><c- n>in_matrix_t</c-><c- o>::</c-><c- n>element_type</c-></code> is a floating-point type
or <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- n>R</c-><c- o>></c-></code> for some floating-point type <code class="highlight"><c- n>R</c-></code>,
if <code class="highlight"><c- n>T</c-></code> is a floating-point type,
and if <code class="highlight"><c- n>T</c-></code> has higher precision than <code class="highlight"><c- n>in_matrix_type</c-><c- o>::</c-><c- n>element_type</c-></code>,
then intermediate terms in each sum use <code class="highlight"><c- n>T</c-></code>'s precision or greater.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.2.13.2" id="infinity-norm-with-default-result-type"><span class="secno">16.9.2.13.2. </span><span class="content">Infinity norm with default result type</span><a class="self-link" href="#infinity-norm-with-default-result-type"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>matrix_inf_norm</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- o>></c->
<c- k>auto</c-> <c- n>matrix_inf_norm</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>)</c-> <c- o>-></c-> <c- d>/* see-below */</c-><c- p>;</c->
</pre>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Let <code class="highlight"><c- n>T</c-></code> be <code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>abs</c-><c- p>(</c-><c- n>A</c-><c- p>[</c-><c- mi>0</c-><c- p>,</c-><c- mi>0</c-><c- p>])</c-></code>.
Then, the one-parameter overload is equivalent to <code class="highlight"><c- n>matrix_inf_norm</c-><c- p>(</c-><c- n>A</c-><c- p>,</c-> <c- n>T</c-><c- p>{});</c-></code>,
and the two-parameter overload is equivalent to <code class="highlight"><c- n>matrix_inf_norm</c-><c- p>(</c-><c- n>exec</c-><c- p>,</c-> <c- n>A</c-><c- p>,</c-> <c- n>T</c-><c- p>{});</c-></code>.</p>
   </ul>
   <h4 class="heading settled" data-level="16.9.3" id="blas-2-functions-linalgalgsblas2"><span class="secno">16.9.3. </span><span class="content">BLAS 2 functions [linalg.algs.blas2]</span><a class="self-link" href="#blas-2-functions-linalgalgsblas2"></a></h4>
   <h5 class="heading settled" data-level="16.9.3.1" id="general-matrix-vector-product-linalgalgsblas2gemv"><span class="secno">16.9.3.1. </span><span class="content">General matrix-vector product [linalg.algs.blas2.gemv]</span><a class="self-link" href="#general-matrix-vector-product-linalgalgsblas2gemv"></a></h5>
   <p><em>[Note:</em> These functions correspond to the BLAS function <code class="highlight"><c- n>xGEMV</c-></code>. --<em>end note]</em></p>
   <p>The following requirements apply to all functions in this section.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>,</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, and</p>
      <li data-md>
       <p><code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> (if applicable).</p>
     </ul>
    <li data-md>
     <p><em>Constraints:</em> For all functions in this section:</p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>in_matrix_t</c-></code> has unique layout; and</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1, <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1, and <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1 (if applicable).</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> (if applicable).</p>
     </ul>
    <li data-md>
     <p><em>Complexity:</em> All algorithms in this Clause with <code class="highlight"><c- n>mdspan</c-></code> parameters
perform a count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
that is linear in <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> times <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.3.1.1" id="overwriting-matrix-vector-product"><span class="secno">16.9.3.1.1. </span><span class="content">Overwriting matrix-vector product</span><a class="self-link" href="#overwriting-matrix-vector-product"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_vector_product</c-><c- p>(</c-><c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                           <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
                           <c- n>out_vector_t</c-> <c- n>y</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_vector_product</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                           <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                           <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
                           <c- n>out_vector_t</c-> <c- n>y</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-></code> in the domain of <code class="highlight"><c- n>y</c-></code> and <code class="highlight"><c- n>N</c-></code> equal to <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-></code> the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> such that <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of <code class="highlight"><c- n>y</c-></code> the product of the matrix <code class="highlight"><c- n>A</c-></code> with the vector <code class="highlight"><c- n>x</c-></code>.</p>
   </ul>
   <p>[<em>Example:</em></p>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>num_rows</c-> <c- o>=</c-> <c- mi>5</c-><c- p>;</c->
<c- n>constexpr</c-> <c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>num_cols</c-> <c- o>=</c-> <c- mi>6</c-><c- p>;</c->

<c- c1>// y = 3.0 * A * x</c->
<c- b>void</c-> <c- nf>scaled_matvec_1</c-><c- p>(</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- n>num_rows</c-><c- p>,</c-> <c- n>num_cols</c-><c- o>>></c-> <c- n>A</c-><c- p>,</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- n>num_cols</c-><c- o>>></c-> <c- n>x</c-><c- p>,</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- n>num_rows</c-><c- o>>></c-> <c- n>y</c-><c- p>)</c->
<c- p>{</c->
  <c- n>matrix_vector_product</c-><c- p>(</c-><c- n>scaled</c-><c- p>(</c-><c- mf>3.0</c-><c- p>,</c-> <c- n>A</c-><c- p>),</c-> <c- n>x</c-><c- p>,</c-> <c- n>y</c-><c- p>);</c->
<c- p>}</c->

<c- c1>// y = 3.0 * A * x + 2.0 * y</c->
<c- b>void</c-> <c- nf>scaled_matvec_2</c-><c- p>(</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- n>num_rows</c-><c- p>,</c-> <c- n>num_cols</c-><c- o>>></c-> <c- n>A</c-><c- p>,</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- n>num_cols</c-><c- o>>></c-> <c- n>x</c-><c- p>,</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- n>num_rows</c-><c- o>>></c-> <c- n>y</c-><c- p>)</c->
<c- p>{</c->
  <c- n>matrix_vector_product</c-><c- p>(</c-><c- n>scaled</c-><c- p>(</c-><c- mf>3.0</c-><c- p>,</c-> <c- n>A</c-><c- p>),</c-> <c- n>x</c-><c- p>,</c->
                        <c- n>scaled</c-><c- p>(</c-><c- mf>2.0</c-><c- p>,</c-> <c- n>y</c-><c- p>),</c-> <c- n>y</c-><c- p>);</c->
<c- p>}</c->

<c- c1>// z = 7.0 times the transpose of A, times y</c->
<c- b>void</c-> <c- nf>scaled_matvec_2</c-><c- p>(</c-><c- n>mdspan</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- n>num_rows</c-><c- p>,</c-> <c- n>num_cols</c-><c- o>>></c-> <c- n>A</c-><c- p>,</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- n>num_rows</c-><c- o>>></c-> <c- n>y</c-><c- p>,</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- b>double</c-><c- p>,</c-> <c- n>extents</c-><c- o>&lt;</c-><c- n>num_cols</c-><c- o>>></c-> <c- n>z</c-><c- p>)</c->
<c- p>{</c->
  <c- n>matrix_vector_product</c-><c- p>(</c-><c- n>scaled</c-><c- p>(</c-><c- mf>7.0</c-><c- p>,</c-> <c- n>transposed</c-><c- p>(</c-><c- n>A</c-><c- p>)),</c-> <c- n>y</c-><c- p>,</c-> <c- n>z</c-><c- p>);</c->
<c- p>}</c->
</pre>
   --<em>end example</em>] 
   <h6 class="heading settled" data-level="16.9.3.1.2" id="updating-matrix-vector-product"><span class="secno">16.9.3.1.2. </span><span class="content">Updating matrix-vector product</span><a class="self-link" href="#updating-matrix-vector-product"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_vector_product</c-><c- p>(</c-><c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                           <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
                           <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
                           <c- n>out_vector_t</c-> <c- n>z</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_vector_product</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                           <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                           <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
                           <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
                           <c- n>out_vector_t</c-> <c- n>z</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-></code> in the domain of <code class="highlight"><c- n>z</c-></code> and <code class="highlight"><c- n>N</c-></code> equal to <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>z</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-> <c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>+</c-> <c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> such that <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of <code class="highlight"><c- n>z</c-></code> the elementwise sum of <code class="highlight"><c- n>y</c-></code>, and the product of the matrix <code class="highlight"><c- n>A</c-></code> with the vector <code class="highlight"><c- n>x</c-></code>.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.3.2" id="symmetric-matrix-vector-product-linalgalgsblas2symv"><span class="secno">16.9.3.2. </span><span class="content">Symmetric matrix-vector product [linalg.algs.blas2.symv]</span><a class="self-link" href="#symmetric-matrix-vector-product-linalgalgsblas2symv"></a></h5>
   <p><em>[Note:</em> These functions correspond to the BLAS functions <code class="highlight"><c- n>xSYMV</c-></code> and <code class="highlight"><c- n>xSPMV</c-></code>. --<em>end note]</em></p>
   <p>The following requirements apply to all functions in this section.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>,</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>,</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, and</p>
      <li data-md>
       <p><code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> (if applicable).</p>
     </ul>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>in_matrix_t</c-></code> either has unique layout, or <code class="highlight"><c- n>layout_blas_packed</c-></code> layout.</p>
      <li data-md>
       <p>If <code class="highlight"><c- n>in_matrix_t</c-></code> has <code class="highlight"><c- n>layout_blas_packed</c-></code> layout, then the
layout’s <code class="highlight"><c- n>Triangle</c-></code> template argument has the same type as
the function’s <code class="highlight"><c- n>Triangle</c-></code> template argument.</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1, <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1, and <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1 (if applicable).</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> (if applicable).</p>
     </ul>
    <li data-md>
     <p><em>Complexity:</em> All algorithms in this Clause with <code class="highlight"><c- n>mdspan</c-></code> parameters
perform a count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
that is linear in <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> times <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Remarks:</em> The functions will only access the triangle of <code class="highlight"><c- n>A</c-></code> specified by the <code class="highlight"><c- n>Triangle</c-></code> argument <code class="highlight"><c- n>t</c-></code>, and will assume for
indices <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> outside that triangle, that <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.3.2.1" id="overwriting-symmetric-matrix-vector-product"><span class="secno">16.9.3.2.1. </span><span class="content">Overwriting symmetric matrix-vector product</span><a class="self-link" href="#overwriting-symmetric-matrix-vector-product"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_vector_product</c-><c- p>(</c-><c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                                     <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
                                     <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
                                     <c- n>out_vector_t</c-> <c- n>y</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_vector_product</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                                     <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                                     <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
                                     <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
                                     <c- n>out_vector_t</c-> <c- n>y</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-></code> in the domain of <code class="highlight"><c- n>y</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-></code> the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>,
plus the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> such that <code class="highlight"><c- n>j</c-><c- p>,</c-><c- n>i</c-></code> is in the domain of A
but not in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of <code class="highlight"><c- n>y</c-></code> the product of the matrix <code class="highlight"><c- n>A</c-></code> with the vector <code class="highlight"><c- n>x</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.3.2.2" id="updating-symmetric-matrix-vector-product"><span class="secno">16.9.3.2.2. </span><span class="content">Updating symmetric matrix-vector product</span><a class="self-link" href="#updating-symmetric-matrix-vector-product"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_vector_product</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- n>out_vector_t</c-> <c- n>z</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_vector_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- n>out_vector_t</c-> <c- n>z</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-></code> in the domain of <code class="highlight"><c- n>y</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>z</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-> <c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code> plus the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>,
plus the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> such that <code class="highlight"><c- n>j</c-><c- p>,</c-><c- n>i</c-></code> is in the domain of A
but not in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of <code class="highlight"><c- n>z</c-></code> the elementwise sum of <code class="highlight"><c- n>y</c-></code>, with the product of the matrix <code class="highlight"><c- n>A</c-></code> with the vector <code class="highlight"><c- n>x</c-></code>.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.3.3" id="hermitian-matrix-vector-product-linalgalgsblas2hemv"><span class="secno">16.9.3.3. </span><span class="content">Hermitian matrix-vector product [linalg.algs.blas2.hemv]</span><a class="self-link" href="#hermitian-matrix-vector-product-linalgalgsblas2hemv"></a></h5>
   <p><em>[Note:</em> These functions correspond to the BLAS functions <code class="highlight"><c- n>xHEMV</c-></code> and <code class="highlight"><c- n>xHPMV</c-></code>. --<em>end note]</em></p>
   <p>The following requirements apply to all functions in this section.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>,</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>,</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, and</p>
      <li data-md>
       <p><code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> (if applicable).</p>
     </ul>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>in_matrix_t</c-></code> either has unique layout, or <code class="highlight"><c- n>layout_blas_packed</c-></code> layout.</p>
      <li data-md>
       <p>If <code class="highlight"><c- n>in_matrix_t</c-></code> has <code class="highlight"><c- n>layout_blas_packed</c-></code> layout, then the
layout’s <code class="highlight"><c- n>Triangle</c-></code> template argument has the same type as
the function’s <code class="highlight"><c- n>Triangle</c-></code> template argument.</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1, <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1, and <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1.</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> (if applicable).</p>
     </ul>
    <li data-md>
     <p><em>Complexity:</em> All algorithms in this Clause with <code class="highlight"><c- n>mdspan</c-></code> parameters
perform a count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
that is linear in <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> times <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Remarks:</em></p>
     <ul>
      <li data-md>
       <p>The functions will only access the triangle of <code class="highlight"><c- n>A</c-></code> specified by
the <code class="highlight"><c- n>Triangle</c-></code> argument <code class="highlight"><c- n>t</c-></code>.</p>
      <li data-md>
       <p>If <code class="highlight"><c- n>inout_matrix_t</c-><c- o>::</c-><c- n>element_type</c-></code> is <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- n>RA</c-><c- o>></c-></code> for some <code class="highlight"><c- n>RA</c-></code>,
then the functions will assume for indices <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> outside that
triangle, that <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code> equals <code class="highlight"><c- n>conj</c-><c- p>(</c-><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>])</c-></code>.  Otherwise, the
functions will assume that <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code>.</p>
     </ul>
   </ul>
   <h6 class="heading settled" data-level="16.9.3.3.1" id="overwriting-hermitian-matrix-vector-product"><span class="secno">16.9.3.3.1. </span><span class="content">Overwriting Hermitian matrix-vector product</span><a class="self-link" href="#overwriting-hermitian-matrix-vector-product"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_vector_product</c-><c- p>(</c-><c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                                     <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
                                     <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
                                     <c- n>out_vector_t</c-> <c- n>y</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_vector_product</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                                     <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                                     <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
                                     <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
                                     <c- n>out_vector_t</c-> <c- n>y</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-></code> in the domain of <code class="highlight"><c- n>y</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-></code> the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>,
plus the sum of <code class="highlight"><c- n>conj</c-><c- p>(</c-><c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>i</c-><c- p>])</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> such that <code class="highlight"><c- n>j</c-><c- p>,</c-><c- n>i</c-></code> is in the domain of A
but not in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of <code class="highlight"><c- n>y</c-></code> the product of the matrix <code class="highlight"><c- n>A</c-></code> with the vector <code class="highlight"><c- n>x</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.3.3.2" id="updating-hermitian-matrix-vector-product"><span class="secno">16.9.3.3.2. </span><span class="content">Updating Hermitian matrix-vector product</span><a class="self-link" href="#updating-hermitian-matrix-vector-product"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_vector_product</c-><c- p>(</c-><c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                                     <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
                                     <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
                                     <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
                                     <c- n>out_vector_t</c-> <c- n>z</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_vector_product</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                                     <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                                     <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
                                     <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
                                     <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
                                     <c- n>out_vector_t</c-> <c- n>z</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-></code> in the domain of <code class="highlight"><c- n>y</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>z</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-> <c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code> plus the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>,
plus the sum of <code class="highlight"><c- n>conj</c-><c- p>(</c-><c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>i</c-><c- p>])</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> such that <code class="highlight"><c- n>j</c-><c- p>,</c-><c- n>i</c-></code> is in the domain of A
but not in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of <code class="highlight"><c- n>z</c-></code> the elementwise sum of <code class="highlight"><c- n>y</c-></code>, and the product of the matrix <code class="highlight"><c- n>A</c-></code> with the vector <code class="highlight"><c- n>x</c-></code>.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.3.4" id="triangular-matrix-vector-product-linalgalgsblas2trmv"><span class="secno">16.9.3.4. </span><span class="content">Triangular matrix-vector product [linalg.algs.blas2.trmv]</span><a class="self-link" href="#triangular-matrix-vector-product-linalgalgsblas2trmv"></a></h5>
   <p><em>[Note:</em> These functions correspond to the BLAS functions <code class="highlight"><c- n>xTRMV</c-></code> and <code class="highlight"><c- n>xTPMV</c-></code>. --<em>end note]</em></p>
   <p>The following requirements apply to all functions in this section.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>,</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>,</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> (if applicable), and</p>
      <li data-md>
       <p><code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> (if applicable).</p>
     </ul>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>in_matrix_t</c-></code> either has unique layout, or <code class="highlight"><c- n>layout_blas_packed</c-></code> layout;</p>
      <li data-md>
       <p>if <code class="highlight"><c- n>in_matrix_t</c-></code> has <code class="highlight"><c- n>layout_blas_packed</c-></code> layout, then the
layout’s <code class="highlight"><c- n>Triangle</c-></code> template argument has the same type as
the function’s <code class="highlight"><c- n>Triangle</c-></code> template argument;</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2;</p>
      <li data-md>
       <p><code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1;</p>
      <li data-md>
       <p><code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1 (if applicable); and</p>
      <li data-md>
       <p><code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1 (if applicable).</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>;</p>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>;</p>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> (if applicable); and</p>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>z</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> (if applicable).</p>
     </ul>
    <li data-md>
     <p><em>Complexity:</em> All algorithms in this Clause with <code class="highlight"><c- n>mdspan</c-></code> parameters
perform a count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
that is linear in <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> times <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Remarks:</em></p>
     <ul>
      <li data-md>
       <p>The functions will only access the triangle of <code class="highlight"><c- n>A</c-></code> specified by
the <code class="highlight"><c- n>Triangle</c-></code> argument <code class="highlight"><c- n>t</c-></code>.</p>
      <li data-md>
       <p>If the <code class="highlight"><c- n>DiagonalStorage</c-></code> template argument has type <code class="highlight"><c- n>implicit_unit_diagonal_t</c-></code>, then the functions will not access the
diagonal of <code class="highlight"><c- n>A</c-></code>, and will assume that that the diagonal elements
of <code class="highlight"><c- n>A</c-></code> all equal one. <em>[Note:</em> This does not imply that the
function needs to be able to form an <code class="highlight"><c- n>element_type</c-></code> value equal to
one. --<em>end note]</em></p>
     </ul>
   </ul>
   <h6 class="heading settled" data-level="16.9.3.4.1" id="overwriting-triangular-matrix-vector-product-linalgalgsblas2trmvov"><span class="secno">16.9.3.4.1. </span><span class="content">Overwriting triangular matrix-vector product [linalg.algs.blas2.trmv.ov]</span><a class="self-link" href="#overwriting-triangular-matrix-vector-product-linalgalgsblas2trmvov"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_vector_product</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>out_vector_t</c-> <c- n>y</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_vector_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>out_vector_t</c-> <c- n>y</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-></code> in the domain of <code class="highlight"><c- n>y</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-></code> the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> in the subset of the domain of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code> and <code class="highlight"><c- n>d</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of <code class="highlight"><c- n>y</c-></code> the product of the matrix <code class="highlight"><c- n>A</c-></code> with the vector <code class="highlight"><c- n>x</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.3.4.2" id="in-place-triangular-matrix-vector-product-linalgalgsblas2trmvin-place"><span class="secno">16.9.3.4.2. </span><span class="content">In-place triangular matrix-vector product [linalg.algs.blas2.trmv.in-place]</span><a class="self-link" href="#in-place-triangular-matrix-vector-product-linalgalgsblas2trmvin-place"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_vector_product</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_vector_t</c-> <c- n>y</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-></code> in the domain of <code class="highlight"><c- n>y</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-></code> the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>y</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> in the subset of the domain of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code> and <code class="highlight"><c- n>d</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Mandates:</em> If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Effects:</em> Overwrites <code class="highlight"><c- n>y</c-></code> (on output) with the product of the matrix <code class="highlight"><c- n>A</c-></code> with the vector <code class="highlight"><c- n>y</c-></code> (on input).</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.3.4.3" id="updating-triangular-matrix-vector-product-linalgalgsblas2trmvup"><span class="secno">16.9.3.4.3. </span><span class="content">Updating triangular matrix-vector product [linalg.algs.blas2.trmv.up]</span><a class="self-link" href="#updating-triangular-matrix-vector-product-linalgalgsblas2trmvup"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_vector_product</c-><c- p>(</c-><c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                                      <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
                                      <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
                                      <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
                                      <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
                                      <c- n>out_vector_t</c-> <c- n>z</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_vector_product</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                                      <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
                                      <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
                                      <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
                                      <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
                                      <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
                                      <c- n>out_vector_t</c-> <c- n>z</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-></code> in the domain of <code class="highlight"><c- n>y</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>z</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-> <c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-></code> plus the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> in the subset of the domain of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code> and <code class="highlight"><c- n>d</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of <code class="highlight"><c- n>z</c-></code> the elementwise sum of <code class="highlight"><c- n>y</c-></code>, with the product of the matrix <code class="highlight"><c- n>A</c-></code> with the vector <code class="highlight"><c- n>x</c-></code>.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.3.5" id="solve-a-triangular-linear-system-linalgalgsblas2trsv"><span class="secno">16.9.3.5. </span><span class="content">Solve a triangular linear system [linalg.algs.blas2.trsv]</span><a class="self-link" href="#solve-a-triangular-linear-system-linalgalgsblas2trsv"></a></h5>
   <p><em>[Note:</em> These functions correspond to the BLAS functions <code class="highlight"><c- n>xTRSV</c-></code> and <code class="highlight"><c- n>xTPSV</c-></code>. --<em>end note]</em></p>
   <p>The following requirements apply to all functions in this section.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>, and</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>b</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2;</p>
      <li data-md>
       <p><code class="highlight"><c- n>b</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1;</p>
      <li data-md>
       <p><code class="highlight"><c- n>in_matrix_t</c-></code> either has unique layout, or <code class="highlight"><c- n>layout_blas_packed</c-></code> layout; and</p>
      <li data-md>
       <p>if <code class="highlight"><c- n>in_matrix_t</c-></code> has <code class="highlight"><c- n>layout_blas_packed</c-></code> layout, then the
layout’s <code class="highlight"><c- n>Triangle</c-></code> template argument has the same type as
the function’s <code class="highlight"><c- n>Triangle</c-></code> template argument.</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>; and</p>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>b</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>b</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Complexity:</em> All algorithms in this Clause with <code class="highlight"><c- n>mdspan</c-></code> parameters
perform a count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
that is linear in <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> times <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Remarks:</em></p>
     <ul>
      <li data-md>
       <p>The functions will only access the triangle of <code class="highlight"><c- n>A</c-></code> specified by
the <code class="highlight"><c- n>Triangle</c-></code> argument <code class="highlight"><c- n>t</c-></code>.</p>
      <li data-md>
       <p>If the <code class="highlight"><c- n>DiagonalStorage</c-></code> template argument has type <code class="highlight"><c- n>implicit_unit_diagonal_t</c-></code>, then the functions will not access the
diagonal of <code class="highlight"><c- n>A</c-></code>, and will assume that that the diagonal elements
of <code class="highlight"><c- n>A</c-></code> all equal one. <em>[Note:</em> This does not imply that the
function needs to be able to form an <code class="highlight"><c- n>element_type</c-></code> value equal to
one. --*end note]</p>
     </ul>
   </ul>
   <h6 class="heading settled" data-level="16.9.3.5.1" id="not-in-place-triangular-solve-linalgalgsblas2trsvnot-in-place"><span class="secno">16.9.3.5.1. </span><span class="content">Not-in-place triangular solve [linalg.algs.blas2.trsv.not-in-place]</span><a class="self-link" href="#not-in-place-triangular-solve-linalgalgsblas2trsvnot-in-place"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_vector_solve</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>b</c-><c- p>,</c->
  <c- n>out_vector_t</c-> <c- n>x</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_vector_solve</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>b</c-><c- p>,</c->
  <c- n>out_vector_t</c-> <c- n>x</c-><c- p>);</c->
</pre>
   <p>If <code class="highlight"><c- n>DiagonalStorage</c-></code> is <code class="highlight"><c- n>explicit_diagonal_t</c-></code>,
then for <code class="highlight"><c- n>i</c-></code> in the domain of <code class="highlight"><c- n>x</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-> <c- n>b</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>-</c-> <c- n>s</c-> <c- o>/</c-> <c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code>,
where <code class="highlight"><c- n>s</c-></code> is the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> in the subset of the domain of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code> and <code class="highlight"><c- n>d</c-></code>.</p>
   <p>If <code class="highlight"><c- n>DiagonalStorage</c-></code> is <code class="highlight"><c- n>implicit_unit_diagonal_t</c-></code>,
then for <code class="highlight"><c- n>i</c-></code> in the domain of <code class="highlight"><c- n>x</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-> <c- n>b</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>-</c-> <c- n>s</c-></code>,
where <code class="highlight"><c- n>s</c-></code> is the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> in the subset of the domain of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code> and <code class="highlight"><c- n>d</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Constraints:</em> <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1 and <code class="highlight"><c- n>b</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1.</p>
    <li data-md>
     <p><em>Mandates:</em> If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of <code class="highlight"><c- n>x</c-></code> the result of solving the
triangular linear system Ax=b.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.3.5.2" id="in-place-triangular-solve-linalgalgsblas2trsvin-place"><span class="secno">16.9.3.5.2. </span><span class="content">In-place triangular solve [linalg.algs.blas2.trsv.in-place]</span><a class="self-link" href="#in-place-triangular-solve-linalgalgsblas2trsvin-place"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_vector_solve</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_vector_t</c-> <c- n>b</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_vector_solve</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_vector_t</c-> <c- n>b</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em></p>
   <p>Performing triangular solve in place hinders parallelization.
However, other <code class="highlight"><c- n>ExecutionPolicy</c-></code>-specific optimizations,
such as vectorization, are still possible.
This is why the <code class="highlight"><c- n>ExecutionPolicy</c-></code> overload exists.</p>
   <p>--<em>end note]</em></p>
   <p>If <code class="highlight"><c- n>DiagonalStorage</c-></code> is <code class="highlight"><c- n>explicit_diagonal_t</c-></code>,
then for <code class="highlight"><c- n>i</c-></code> in the domain of <code class="highlight"><c- n>x</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>b</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-> <c- n>b</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>-</c-> <c- n>s</c-> <c- o>/</c-> <c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code>,
where <code class="highlight"><c- n>s</c-></code> is the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>b</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> in the subset of the domain of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code> and <code class="highlight"><c- n>d</c-></code>.</p>
   <p>If <code class="highlight"><c- n>DiagonalStorage</c-></code> is <code class="highlight"><c- n>implicit_unit_diagonal_t</c-></code>,
then for <code class="highlight"><c- n>i</c-></code> in the domain of <code class="highlight"><c- n>x</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>b</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>=</c-> <c- n>b</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>-</c-> <c- n>s</c-></code>,
where <code class="highlight"><c- n>s</c-></code> is the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>b</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> in the subset of the domain of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code> and <code class="highlight"><c- n>d</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>b</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Mandates:</em> If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>b</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>,
then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>b</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Effects:</em> Overwrites <code class="highlight"><c- n>b</c-></code> with the result of solving the triangular
linear system Ax=b for x.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.3.6" id="rank-1-outer-product-update-of-a-matrix-linalgalgsblas2rank1"><span class="secno">16.9.3.6. </span><span class="content">Rank-1 (outer product) update of a matrix [linalg.algs.blas2.rank1]</span><a class="self-link" href="#rank-1-outer-product-update-of-a-matrix-linalgalgsblas2rank1"></a></h5>
   <h6 class="heading settled" data-level="16.9.3.6.1" id="nonsymmetric-nonconjugated-rank-1-update-linalgalgsblas2rank1geru"><span class="secno">16.9.3.6.1. </span><span class="content">Nonsymmetric nonconjugated rank-1 update [linalg.algs.blas2.rank1.geru]</span><a class="self-link" href="#nonsymmetric-nonconjugated-rank-1-update-linalgalgsblas2rank1geru"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_rank_1_update</c-><c- p>(</c->
  <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_rank_1_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em> This function corresponds to the BLAS functions <code class="highlight"><c- n>xGER</c-></code> (for
real element types) and <code class="highlight"><c- n>xGERU</c-></code> (for complex element types). --<em>end
note]</em></p>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>A</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>+=</c-> <c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>*</c-> <c- n>y</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, and</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Constraints:</em> <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1,
and <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1.</p>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to <code class="highlight"><c- n>A</c-></code> on output the sum of <code class="highlight"><c- n>A</c-></code> on input, and the
outer product of <code class="highlight"><c- n>x</c-></code> and <code class="highlight"><c- n>y</c-></code>.</p>
    <li data-md>
     <p><em>Complexity:</em> The count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
is linear in <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> times <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
   </ul>
   <p><em>[Note:</em> Users can get <code class="highlight"><c- n>xGERC</c-></code> behavior by giving the second argument
as the result of <code class="highlight"><c- n>conjugated</c-></code>.  Alternately, they can use the shortcut <code class="highlight"><c- n>matrix_rank_1_update_c</c-></code> below. --<em>end note]</em></p>
   <h6 class="heading settled" data-level="16.9.3.6.2" id="nonsymmetric-conjugated-rank-1-update-linalgalgsblas2rank1gerc"><span class="secno">16.9.3.6.2. </span><span class="content">Nonsymmetric conjugated rank-1 update [linalg.algs.blas2.rank1.gerc]</span><a class="self-link" href="#nonsymmetric-conjugated-rank-1-update-linalgalgsblas2rank1gerc"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_rank_1_update_c</c-><c- p>(</c->
  <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_rank_1_update_c</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em> This function corresponds to the BLAS functions <code class="highlight"><c- n>xGER</c-></code> (for
real element types) and <code class="highlight"><c- n>xGERC</c-></code> (for complex element types). --<em>end
note]</em></p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Equivalent to <code class="highlight"><c- n>matrix_rank_1_update</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- n>conjugated</c-><c- p>(</c-><c- n>y</c-><c- p>),</c-> <c- n>A</c-><c- p>);</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.3.6.3" id="rank-1-update-of-a-symmetric-matrix-linalgalgsblas2rank1syr"><span class="secno">16.9.3.6.3. </span><span class="content">Rank-1 update of a Symmetric matrix [linalg.algs.blas2.rank1.syr]</span><a class="self-link" href="#rank-1-update-of-a-symmetric-matrix-linalgalgsblas2rank1syr"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_rank_1_update</c-><c- p>(</c->
  <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_rank_1_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_rank_1_update</c-><c- p>(</c->
  <c- n>T</c-> <c- n>alpha</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_rank_1_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>T</c-> <c- n>alpha</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em></p>
   <p>These functions correspond to the BLAS functions <code class="highlight"><c- n>xSYR</c-></code> and <code class="highlight"><c- n>xSPR</c-></code>.</p>
   <p>They have overloads taking a scaling factor <code class="highlight"><c- n>alpha</c-></code>, because it would be
impossible to express updates like C = C - x x^T otherwise.</p>
   <p>--<em>end note]</em></p>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>+=</c-> <c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-></code> for overloads without an <code class="highlight"><c- n>alpha</c-></code> parameter, and <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>+=</c-> <c- n>alpha</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-></code> for overloads with an <code class="highlight"><c- n>alpha</c-></code> parameter.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>, and</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2 and <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1.</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-></code> either has unique layout, or <code class="highlight"><c- n>layout_blas_packed</c-></code> layout.</p>
      <li data-md>
       <p>if <code class="highlight"><c- n>A</c-></code> has <code class="highlight"><c- n>layout_blas_packed</c-></code> layout, then the layout’s <code class="highlight"><c- n>Triangle</c-></code> template argument has the same type as the function’s <code class="highlight"><c- n>Triangle</c-></code> template argument.</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Effects:</em></p>
     <ul>
      <li data-md>
       <p>Overloads without an <code class="highlight"><c- n>alpha</c-></code> parameter assign to <code class="highlight"><c- n>A</c-></code> on output,
the elementwise sum of <code class="highlight"><c- n>A</c-></code> on input,
with (the outer product of <code class="highlight"><c- n>x</c-></code> and <code class="highlight"><c- n>x</c-></code>).</p>
      <li data-md>
       <p>Overloads with an <code class="highlight"><c- n>alpha</c-></code> parameter assign to <code class="highlight"><c- n>A</c-></code> on output,
the elementwise sum of <code class="highlight"><c- n>A</c-></code> on input,
with the product of alpha and (the outer product of <code class="highlight"><c- n>x</c-></code> and <code class="highlight"><c- n>x</c-></code>).</p>
     </ul>
    <li data-md>
     <p><em>Complexity:</em> The count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
is linear in <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> times <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Remarks:</em> The functions will only access the triangle of <code class="highlight"><c- n>A</c-></code> specified by the <code class="highlight"><c- n>Triangle</c-></code> argument <code class="highlight"><c- n>t</c-></code>, and will assume for
indices <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> outside that triangle, that <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.3.6.4" id="rank-1-update-of-a-hermitian-matrix-linalgalgsblas2rank1her"><span class="secno">16.9.3.6.4. </span><span class="content">Rank-1 update of a Hermitian matrix [linalg.algs.blas2.rank1.her]</span><a class="self-link" href="#rank-1-update-of-a-hermitian-matrix-linalgalgsblas2rank1her"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_rank_1_update</c-><c- p>(</c->
  <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_rank_1_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_rank_1_update</c-><c- p>(</c->
  <c- n>T</c-> <c- n>alpha</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_rank_1_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>T</c-> <c- n>alpha</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em></p>
   <p>These functions correspond to the BLAS functions <code class="highlight"><c- n>xHER</c-></code> and <code class="highlight"><c- n>xHPR</c-></code>.</p>
   <p>They have overloads taking a scaling factor <code class="highlight"><c- n>alpha</c-></code>, because it would be
impossible to express the update A = A - x x^H otherwise.</p>
   <p>--<em>end note]</em></p>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>+=</c-> <c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>*</c-> <c- n>conj</c-><c- p>(</c-><c- n>x</c-><c- p>[</c-><c- n>j</c-><c- p>])</c-></code> for overloads without an <code class="highlight"><c- n>alpha</c-></code> parameter, and <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>+=</c-> <c- n>alpha</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>*</c-> <c- n>conj</c-><c- p>(</c-><c- n>x</c-><c- p>[</c-><c- n>j</c-><c- p>])</c-></code> for overloads without an <code class="highlight"><c- n>alpha</c-></code> parameter.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>; and</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2 and <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1.</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-></code> either has unique layout, or <code class="highlight"><c- n>layout_blas_packed</c-></code> layout.</p>
      <li data-md>
       <p>If <code class="highlight"><c- n>A</c-></code> has <code class="highlight"><c- n>layout_blas_packed</c-></code> layout, then the layout’s <code class="highlight"><c- n>Triangle</c-></code> template argument has the same type as the function’s <code class="highlight"><c- n>Triangle</c-></code> template argument.</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Effects:</em></p>
     <ul>
      <li data-md>
       <p>Overloads without <code class="highlight"><c- n>alpha</c-></code> assign to <code class="highlight"><c- n>A</c-></code> on output, the elementwise
sum of <code class="highlight"><c- n>A</c-></code> on input, with (the outer product of <code class="highlight"><c- n>x</c-></code> and the
conjugate of <code class="highlight"><c- n>x</c-></code>).</p>
      <li data-md>
       <p>Overloads with <code class="highlight"><c- n>alpha</c-></code> assign to <code class="highlight"><c- n>A</c-></code> on output, the elementwise
sum of <code class="highlight"><c- n>A</c-></code> on input, with alpha times (the outer product of <code class="highlight"><c- n>x</c-></code> and the conjugate of <code class="highlight"><c- n>x</c-></code>).</p>
     </ul>
    <li data-md>
     <p><em>Complexity:</em> The count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
is linear in <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> times <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Remarks:</em></p>
     <ul>
      <li data-md>
       <p>The functions will only access the triangle of <code class="highlight"><c- n>A</c-></code> specified by
the <code class="highlight"><c- n>Triangle</c-></code> argument <code class="highlight"><c- n>t</c-></code>.</p>
      <li data-md>
       <p>If <code class="highlight"><c- n>inout_matrix_t</c-><c- o>::</c-><c- n>element_type</c-></code> is <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- n>RA</c-><c- o>></c-></code> for some <code class="highlight"><c- n>RA</c-></code>,
then the functions will assume for indices <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> outside that
triangle, that <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code> equals <code class="highlight"><c- n>conj</c-><c- p>(</c-><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>])</c-></code>.  Otherwise, the
functions will assume that <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code>.</p>
     </ul>
   </ul>
   <h5 class="heading settled" data-level="16.9.3.7" id="rank-2-update-of-a-symmetric-matrix-linalgalgsblas2rank2syr2"><span class="secno">16.9.3.7. </span><span class="content">Rank-2 update of a symmetric matrix [linalg.algs.blas2.rank2.syr2]</span><a class="self-link" href="#rank-2-update-of-a-symmetric-matrix-linalgalgsblas2rank2syr2"></a></h5>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_rank_2_update</c-><c- p>(</c->
  <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_rank_2_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em> These functions correspond to the BLAS functions <code class="highlight"><c- n>xSYR2</c-></code> and <code class="highlight"><c- n>xSPR2</c-></code>. --<em>end note]</em></p>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>+=</c-> <c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>*</c-> <c- n>y</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-> <c- o>+</c-> <c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>*</c-> <c- n>x</c-><c- p>[</c-><c- n>j</c-><c- p>]</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>,</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, and</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1, and <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1.</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-></code> either has unique layout, or <code class="highlight"><c- n>layout_blas_packed</c-></code> layout.</p>
      <li data-md>
       <p>If <code class="highlight"><c- n>A</c-></code> has <code class="highlight"><c- n>layout_blas_packed</c-></code> layout, then the layout’s <code class="highlight"><c- n>Triangle</c-></code> template argument has the same type as the function’s <code class="highlight"><c- n>Triangle</c-></code> template argument.</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to <code class="highlight"><c- n>A</c-></code> on output the sum of <code class="highlight"><c- n>A</c-></code> on input, the
outer product of <code class="highlight"><c- n>x</c-></code> and <code class="highlight"><c- n>y</c-></code>, and the outer product of <code class="highlight"><c- n>y</c-></code> and <code class="highlight"><c- n>x</c-></code>.</p>
    <li data-md>
     <p><em>Complexity:</em> The count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
is linear in <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> times <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Remarks:</em> The functions will only access the triangle of <code class="highlight"><c- n>A</c-></code> specified by the <code class="highlight"><c- n>Triangle</c-></code> argument <code class="highlight"><c- n>t</c-></code>, and will assume for
indices <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> outside that triangle, that <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code>.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.3.8" id="rank-2-update-of-a-hermitian-matrix-linalgalgsblas2rank2her2"><span class="secno">16.9.3.8. </span><span class="content">Rank-2 update of a Hermitian matrix [linalg.algs.blas2.rank2.her2]</span><a class="self-link" href="#rank-2-update-of-a-hermitian-matrix-linalgalgsblas2rank2her2"></a></h5>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_rank_2_update</c-><c- p>(</c->
  <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_rank_2_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_vector_1_t</c-> <c- n>x</c-><c- p>,</c->
  <c- n>in_vector_2_t</c-> <c- n>y</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em> These functions correspond to the BLAS functions <code class="highlight"><c- n>xHER2</c-></code> and <code class="highlight"><c- n>xHPR2</c-></code>. --<em>end note]</em></p>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>+=</c-> <c- n>x</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>*</c-> <c- n>conj</c-><c- p>(</c-><c- n>y</c-><c- p>[</c-><c- n>j</c-><c- p>])</c-> <c- o>+</c-> <c- n>y</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>*</c-> <c- n>conj</c-><c- p>(</c-><c- n>x</c-><c- p>[</c-><c- n>j</c-><c- p>])</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>,</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, and</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1, and <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 1.</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-></code> either has unique layout, or <code class="highlight"><c- n>layout_blas_packed</c-></code> layout.</p>
      <li data-md>
       <p>If <code class="highlight"><c- n>A</c-></code> has <code class="highlight"><c- n>layout_blas_packed</c-></code> layout, then the layout’s <code class="highlight"><c- n>Triangle</c-></code> template argument has the same type as the function’s <code class="highlight"><c- n>Triangle</c-></code> template argument.</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to <code class="highlight"><c- n>A</c-></code> on output the sum of <code class="highlight"><c- n>A</c-></code> on input,
the outer product of <code class="highlight"><c- n>x</c-></code> and the conjugate of <code class="highlight"><c- n>y</c-></code>,
and the outer product of <code class="highlight"><c- n>y</c-></code> and the conjugate of <code class="highlight"><c- n>x</c-></code>.</p>
    <li data-md>
     <p><em>Complexity:</em> The count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
is linear in <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> times <code class="highlight"><c- n>y</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Remarks:</em></p>
     <ul>
      <li data-md>
       <p>The functions will only access the triangle of <code class="highlight"><c- n>A</c-></code> specified by the <code class="highlight"><c- n>Triangle</c-></code> argument <code class="highlight"><c- n>t</c-></code>.</p>
      <li data-md>
       <p>If <code class="highlight"><c- n>inout_matrix_t</c-><c- o>::</c-><c- n>element_type</c-></code> is <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- n>RA</c-><c- o>></c-></code> for some <code class="highlight"><c- n>RA</c-></code>,
then the functions will assume for indices <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> outside that
triangle, that <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code> equals <code class="highlight"><c- n>conj</c-><c- p>(</c-><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>])</c-></code>.  Otherwise, the
functions will assume that <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code>.</p>
     </ul>
   </ul>
   <h4 class="heading settled" data-level="16.9.4" id="blas-3-functions-linalgalgsblas3"><span class="secno">16.9.4. </span><span class="content">BLAS 3 functions [linalg.algs.blas3]</span><a class="self-link" href="#blas-3-functions-linalgalgsblas3"></a></h4>
   <h5 class="heading settled" data-level="16.9.4.1" id="general-matrix-matrix-product-linalgalgsblas3gemm"><span class="secno">16.9.4.1. </span><span class="content">General matrix-matrix product [linalg.algs.blas3.gemm]</span><a class="self-link" href="#general-matrix-matrix-product-linalgalgsblas3gemm"></a></h5>
   <p><em>[Note:</em> These functions correspond to the BLAS function <code class="highlight"><c- n>xGEMM</c-></code>.
--<em>end note]</em></p>
   <p>The following requirements apply to all functions in this section.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>E</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> (if applicable),</p>
      <li data-md>
       <p><code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>E</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> (if applicable),</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>,</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, and</p>
      <li data-md>
       <p><code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>in_matrix_1_t</c-></code>, <code class="highlight"><c- n>in_matrix_2_t</c-></code>, <code class="highlight"><c- n>in_matrix_3_t</c-></code> (if applicable),
and <code class="highlight"><c- n>out_matrix_t</c-></code> have unique layout.</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, and <code class="highlight"><c- n>E</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> (if applicable) equals 2.</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>For all <code class="highlight"><c- n>r</c-></code> in 0, 1, ..., <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> - 1, if neither <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>E</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>E</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> (if applicable).</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Complexity:</em> For all algorithms in this Clause,
the count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
is linear in <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> times <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> times <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.4.1.1" id="overwriting-general-matrix-matrix-product"><span class="secno">16.9.4.1.1. </span><span class="content">Overwriting general matrix-matrix product</span><a class="self-link" href="#overwriting-general-matrix-matrix-product"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_product</c-><c- p>(</c-><c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
                    <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
                    <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_product</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                    <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
                    <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
                    <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>C</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-></code> the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>*</c-> <c- n>B</c-><c- p>[</c-><c- n>k</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k</c-></code> such that <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of the matrix <code class="highlight"><c- n>C</c-></code> the product of
the matrices <code class="highlight"><c- n>A</c-></code> and <code class="highlight"><c- n>B</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.4.1.2" id="updating-general-matrix-matrix-product"><span class="secno">16.9.4.1.2. </span><span class="content">Updating general matrix-matrix product</span><a class="self-link" href="#updating-general-matrix-matrix-product"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_product</c-><c- p>(</c-><c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
                    <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
                    <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
                    <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>matrix_product</c-><c- p>(</c-><c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
                    <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
                    <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
                    <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
                    <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>C</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-> <c- n>E</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> plus the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>*</c-> <c- n>B</c-><c- p>[</c-><c- n>k</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k</c-></code> such that <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of the matrix <code class="highlight"><c- n>C</c-></code> on output, the
elementwise sum of <code class="highlight"><c- n>E</c-></code> and the product of the matrices <code class="highlight"><c- n>A</c-></code> and <code class="highlight"><c- n>B</c-></code>.</p>
    <li data-md>
     <p><em>Remarks:</em> <code class="highlight"><c- n>C</c-></code> and <code class="highlight"><c- n>E</c-></code> may refer to the same matrix.
If so, then they must have the same layout.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.4.2" id="symmetric-matrix-matrix-product-linalgalgsblas3symm"><span class="secno">16.9.4.2. </span><span class="content">Symmetric matrix-matrix product [linalg.algs.blas3.symm]</span><a class="self-link" href="#symmetric-matrix-matrix-product-linalgalgsblas3symm"></a></h5>
   <p><em>[Note:</em></p>
   <p>These functions correspond to the BLAS function <code class="highlight"><c- n>xSYMM</c-></code>.</p>
   <p>Unlike the symmetric rank-1 or rank-k update functions, these functions assume
that the input matrix <code class="highlight"><c- n>A</c-></code> -- not the output matrix -- is symmetric.</p>
   <p>--<em>end note]</em></p>
   <p>The following requirements apply to all functions in this section.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>,</p>
      <li data-md>
       <p><code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>E</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> (if applicable), and</p>
      <li data-md>
       <p><code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>E</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> (if applicable).</p>
     </ul>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>in_matrix_1_t</c-></code> either has unique layout,
or <code class="highlight"><c- n>layout_blas_packed</c-></code> layout.</p>
      <li data-md>
       <p><code class="highlight"><c- n>in_matrix_2_t</c-></code>, <code class="highlight"><c- n>in_matrix_3_t</c-></code> (if applicable),
and <code class="highlight"><c- n>out_matrix_t</c-></code> have unique layout.</p>
      <li data-md>
       <p>If <code class="highlight"><c- n>in_matrix_1_t</c-></code> has <code class="highlight"><c- n>layout_blas_packed</c-></code> layout, then the
layout’s <code class="highlight"><c- n>Triangle</c-></code> template argument has the same type as
the function’s <code class="highlight"><c- n>Triangle</c-></code> template argument.</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, and <code class="highlight"><c- n>E</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> (if applicable) equals 2.</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>For all <code class="highlight"><c- n>r</c-></code> in 0, 1, ..., <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> - 1, if neither <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>E</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>E</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> (if applicable).</p>
     </ul>
    <li data-md>
     <p><em>Remarks:</em></p>
     <ul>
      <li data-md>
       <p>The functions will only access the triangle of <code class="highlight"><c- n>A</c-></code> specified by
the <code class="highlight"><c- n>Triangle</c-></code> argument <code class="highlight"><c- n>t</c-></code>, and will assume for indices <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> outside that triangle, that <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code>.</p>
      <li data-md>
       <p><em>Remarks:</em> <code class="highlight"><c- n>C</c-></code> and <code class="highlight"><c- n>E</c-></code> (if applicable) may refer to the same
matrix.  If so, then they must have the same layout.</p>
     </ul>
   </ul>
   <p>The following requirements apply to all overloads of <code class="highlight"><c- n>symmetric_matrix_left_product</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>,</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, and</p>
      <li data-md>
       <p><code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>;</p>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>; and</p>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Complexity:</em> The count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
is linear in <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> times <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> times <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
   </ul>
   <p>The following requirements apply to all overloads of <code class="highlight"><c- n>symmetric_matrix_right_product</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>,</p>
      <li data-md>
       <p><code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, and</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>;</p>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>; and</p>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Complexity:</em> The count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
is linear in <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> times <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> times <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.4.2.1" id="overwriting-symmetric-matrix-matrix-left-product-linalgalgsblas3symmovleft"><span class="secno">16.9.4.2.1. </span><span class="content">Overwriting symmetric matrix-matrix left product [linalg.algs.blas3.symm.ov.left]</span><a class="self-link" href="#overwriting-symmetric-matrix-matrix-left-product-linalgalgsblas3symmovleft"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_left_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_left_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>C</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-> <c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-> <c- o>*</c-> <c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> plus the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k1</c-><c- p>]</c-> <c- o>*</c-> <c- n>B</c-><c- p>[</c-><c- n>k1</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k1</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> such that <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k1</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>,
plus the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>k2</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-> <c- o>*</c-> <c- n>B</c-><c- p>[</c-><c- n>k2</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k2</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> such that <code class="highlight"><c- n>k2</c-><c- p>,</c-><c- n>i</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of the matrix <code class="highlight"><c- n>C</c-></code> the product of the matrices <code class="highlight"><c- n>A</c-></code> and <code class="highlight"><c- n>B</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.4.2.2" id="overwriting-symmetric-matrix-matrix-right-product-linalgalgsblas3symmovright"><span class="secno">16.9.4.2.2. </span><span class="content">Overwriting symmetric matrix-matrix right product [linalg.algs.blas3.symm.ov.right]</span><a class="self-link" href="#overwriting-symmetric-matrix-matrix-right-product-linalgalgsblas3symmovright"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_right_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_right_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>C</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-> <c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code> plus the sum of <code class="highlight"><c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k1</c-><c- p>]</c-> <c- o>*</c-> <c- n>A</c-><c- p>[</c-><c- n>k1</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k1</c-></code> not equal to <code class="highlight"><c- n>j</c-></code> such that <code class="highlight"><c- n>k1</c-><c- p>,</c-><c- n>j</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>,
plus the sum of <code class="highlight"><c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k2</c-><c- p>]</c-> <c- o>*</c-> <c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>k2</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k2</c-></code> not equal to <code class="highlight"><c- n>j</c-></code> such that <code class="highlight"><c- n>k2</c-><c- p>,</c-><c- n>j</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of the matrix <code class="highlight"><c- n>C</c-></code> the product of the matrices <code class="highlight"><c- n>B</c-></code> and <code class="highlight"><c- n>A</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.4.2.3" id="updating-symmetric-matrix-matrix-left-product-linalgalgsblas3symmupleft"><span class="secno">16.9.4.2.3. </span><span class="content">Updating symmetric matrix-matrix left product [linalg.algs.blas3.symm.up.left]</span><a class="self-link" href="#updating-symmetric-matrix-matrix-left-product-linalgalgsblas3symmupleft"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_left_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_left_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>C</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-> <c- n>E</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>+</c-> <c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-> <c- o>*</c-> <c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> plus the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k1</c-><c- p>]</c-> <c- o>*</c-> <c- n>B</c-><c- p>[</c-><c- n>k1</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k1</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> such that <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k1</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>,
plus the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>k2</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-> <c- o>*</c-> <c- n>B</c-><c- p>[</c-><c- n>k2</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k2</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> such that <code class="highlight"><c- n>k2</c-><c- p>,</c-><c- n>i</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> assigns to the elements of the matrix <code class="highlight"><c- n>C</c-></code> on output,
the elementwise sum of <code class="highlight"><c- n>E</c-></code> and the product of the matrices <code class="highlight"><c- n>A</c-></code> and <code class="highlight"><c- n>B</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.4.2.4" id="updating-symmetric-matrix-matrix-right-product-linalgalgsblas3symmupright"><span class="secno">16.9.4.2.4. </span><span class="content">Updating symmetric matrix-matrix right product [linalg.algs.blas3.symm.up.right]</span><a class="self-link" href="#updating-symmetric-matrix-matrix-right-product-linalgalgsblas3symmupright"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_right_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_right_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>C</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-> <c- n>E</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>+</c-> <c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code> plus the sum of <code class="highlight"><c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k1</c-><c- p>]</c-> <c- o>*</c-> <c- n>A</c-><c- p>[</c-><c- n>k1</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k1</c-></code> not equal to <code class="highlight"><c- n>j</c-></code> such that <code class="highlight"><c- n>k1</c-><c- p>,</c-><c- n>j</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>,
plus the sum of <code class="highlight"><c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k2</c-><c- p>]</c-> <c- o>*</c-> <c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>k2</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k2</c-></code> not equal to <code class="highlight"><c- n>j</c-></code> such that <code class="highlight"><c- n>k2</c-><c- p>,</c-><c- n>j</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> assigns to the elements of the matrix <code class="highlight"><c- n>C</c-></code> on output, the
elementwise sum of <code class="highlight"><c- n>E</c-></code> and the product of the matrices <code class="highlight"><c- n>B</c-></code> and <code class="highlight"><c- n>A</c-></code>.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.4.3" id="hermitian-matrix-matrix-product-linalgalgsblas3hemm"><span class="secno">16.9.4.3. </span><span class="content">Hermitian matrix-matrix product [linalg.algs.blas3.hemm]</span><a class="self-link" href="#hermitian-matrix-matrix-product-linalgalgsblas3hemm"></a></h5>
   <p><em>[Note:</em></p>
   <p>These functions correspond to the BLAS function <code class="highlight"><c- n>xHEMM</c-></code>.</p>
   <p>Unlike the Hermitian rank-1 or rank-k update functions, these functions assume
that the input matrix -- not the output matrix -- is Hermitian.</p>
   <p>--<em>end note]</em></p>
   <p>The following requirements apply to all functions in this section.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>,</p>
      <li data-md>
       <p><code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>E</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> (if applicable), and</p>
      <li data-md>
       <p><code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>E</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> (if applicable).</p>
     </ul>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>in_matrix_1_t</c-></code> either has unique layout,
or <code class="highlight"><c- n>layout_blas_packed</c-></code> layout.</p>
      <li data-md>
       <p><code class="highlight"><c- n>in_matrix_2_t</c-></code>, <code class="highlight"><c- n>in_matrix_3_t</c-></code> (if applicable), and <code class="highlight"><c- n>out_matrix_t</c-></code> have unique layout.</p>
      <li data-md>
       <p>If <code class="highlight"><c- n>in_matrix_1_t</c-></code> has <code class="highlight"><c- n>layout_blas_packed</c-></code> layout, then the
layout’s <code class="highlight"><c- n>Triangle</c-></code> template argument has the same type as
the function’s <code class="highlight"><c- n>Triangle</c-></code> template argument.</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, and <code class="highlight"><c- n>E</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> (if applicable) equals 2.</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>For all <code class="highlight"><c- n>r</c-></code> in 0, 1, ..., <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> - 1, if neither <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>E</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>E</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> (if applicable).</p>
     </ul>
    <li data-md>
     <p><em>Remarks:</em></p>
     <ul>
      <li data-md>
       <p>The functions will only access the triangle of <code class="highlight"><c- n>A</c-></code> specified by
the <code class="highlight"><c- n>Triangle</c-></code> argument <code class="highlight"><c- n>t</c-></code>.</p>
      <li data-md>
       <p>If <code class="highlight"><c- n>in_matrix_1_t</c-><c- o>::</c-><c- n>element_type</c-></code> is <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- n>RA</c-><c- o>></c-></code> for some <code class="highlight"><c- n>RA</c-></code>,
then the functions will assume for indices <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> outside that
triangle, that <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code> equals <code class="highlight"><c- n>conj</c-><c- p>(</c-><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>])</c-></code>.  Otherwise, the
functions will assume that <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code>.</p>
      <li data-md>
       <p><code class="highlight"><c- n>C</c-></code> and <code class="highlight"><c- n>E</c-></code> (if applicable) may refer to the same matrix.
If so, then they must have the same layout.</p>
     </ul>
   </ul>
   <p>The following requirements apply to all overloads of <code class="highlight"><c- n>hermitian_matrix_left_product</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>,</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, and</p>
      <li data-md>
       <p><code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>;</p>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>; and</p>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Complexity:</em> The count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
is linear in <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> times <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> times <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
   </ul>
   <p>The following requirements apply to all overloads of <code class="highlight"><c- n>hermitian_matrix_right_product</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>,</p>
      <li data-md>
       <p><code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, and</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>;</p>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>; and</p>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Complexity:</em> The count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
is linear in <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> times <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> times <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.4.3.1" id="overwriting-hermitian-matrix-matrix-left-product-linalgalgsblas3hemmovleft"><span class="secno">16.9.4.3.1. </span><span class="content">Overwriting Hermitian matrix-matrix left product [linalg.algs.blas3.hemm.ov.left]</span><a class="self-link" href="#overwriting-hermitian-matrix-matrix-left-product-linalgalgsblas3hemmovleft"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_left_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_left_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>C</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-> <c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-> <c- o>*</c-> <c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> plus the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k1</c-><c- p>]</c-> <c- o>*</c-> <c- n>B</c-><c- p>[</c-><c- n>k1</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k1</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> such that <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k1</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>,
plus the sum of <code class="highlight"><c- n>conj</c-><c- p>(</c-><c- n>A</c-><c- p>[</c-><c- n>k2</c-><c- p>,</c-><c- n>i</c-><c- p>])</c-> <c- o>*</c-> <c- n>B</c-><c- p>[</c-><c- n>k2</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k2</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> such that <code class="highlight"><c- n>k2</c-><c- p>,</c-><c- n>i</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of the matrix <code class="highlight"><c- n>C</c-></code> the product of
the matrices <code class="highlight"><c- n>A</c-></code> and <code class="highlight"><c- n>B</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.4.3.2" id="overwriting-hermitian-matrix-matrix-right-product-linalgalgsblas3hemmovright"><span class="secno">16.9.4.3.2. </span><span class="content">Overwriting Hermitian matrix-matrix right product [linalg.algs.blas3.hemm.ov.right]</span><a class="self-link" href="#overwriting-hermitian-matrix-matrix-right-product-linalgalgsblas3hemmovright"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_right_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_right_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>C</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-> <c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code> plus the sum of <code class="highlight"><c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k1</c-><c- p>]</c-> <c- o>*</c-> <c- n>A</c-><c- p>[</c-><c- n>k1</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k1</c-></code> not equal to <code class="highlight"><c- n>j</c-></code> such that <code class="highlight"><c- n>k1</c-><c- p>,</c-><c- n>j</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>,
plus the sum of <code class="highlight"><c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k2</c-><c- p>]</c-> <c- o>*</c-> <c- n>conj</c-><c- p>(</c-><c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>k2</c-><c- p>])</c-></code> for all <code class="highlight"><c- n>k2</c-></code> not equal to <code class="highlight"><c- n>j</c-></code> such that <code class="highlight"><c- n>k2</c-><c- p>,</c-><c- n>j</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of the matrix <code class="highlight"><c- n>C</c-></code> the product of
the matrices <code class="highlight"><c- n>B</c-></code> and <code class="highlight"><c- n>A</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.4.3.3" id="updating-hermitian-matrix-matrix-left-product-linalgalgsblas3hemmupleft"><span class="secno">16.9.4.3.3. </span><span class="content">Updating Hermitian matrix-matrix left product [linalg.algs.blas3.hemm.up.left]</span><a class="self-link" href="#updating-hermitian-matrix-matrix-left-product-linalgalgsblas3hemmupleft"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_left_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_left_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>C</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-> <c- n>E</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>+</c-> <c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-> <c- o>*</c-> <c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> plus the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k1</c-><c- p>]</c-> <c- o>*</c-> <c- n>B</c-><c- p>[</c-><c- n>k1</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k1</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> such that <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k1</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>,
plus the sum of <code class="highlight"><c- n>conj</c-><c- p>(</c-><c- n>A</c-><c- p>[</c-><c- n>k2</c-><c- p>,</c-><c- n>i</c-><c- p>])</c-> <c- o>*</c-> <c- n>B</c-><c- p>[</c-><c- n>k2</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k2</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> such that <code class="highlight"><c- n>k2</c-><c- p>,</c-><c- n>i</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of the matrix <code class="highlight"><c- n>C</c-></code> on output,
the elementwise sum of <code class="highlight"><c- n>E</c-></code> and the product of the matrices <code class="highlight"><c- n>A</c-></code> and <code class="highlight"><c- n>B</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.4.3.4" id="updating-hermitian-matrix-matrix-right-product-linalgalgsblas3hemmupright"><span class="secno">16.9.4.3.4. </span><span class="content">Updating Hermitian matrix-matrix right product [linalg.algs.blas3.hemm.up.right]</span><a class="self-link" href="#updating-hermitian-matrix-matrix-right-product-linalgalgsblas3hemmupright"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_right_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_right_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>C</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-> <c- n>E</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>+</c-> <c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code> plus the sum of <code class="highlight"><c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k1</c-><c- p>]</c-> <c- o>*</c-> <c- n>A</c-><c- p>[</c-><c- n>k1</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k1</c-></code> not equal to <code class="highlight"><c- n>j</c-></code> such that <code class="highlight"><c- n>k1</c-><c- p>,</c-><c- n>j</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>,
plus the sum of <code class="highlight"><c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k2</c-><c- p>]</c-> <c- o>*</c-> <c- n>conj</c-><c- p>(</c-><c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>k2</c-><c- p>])</c-></code> for all <code class="highlight"><c- n>k2</c-></code> not equal to <code class="highlight"><c- n>j</c-></code> such that <code class="highlight"><c- n>k2</c-><c- p>,</c-><c- n>j</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of the matrix <code class="highlight"><c- n>C</c-></code> on output, the
elementwise sum of <code class="highlight"><c- n>E</c-></code> and the product of the matrices <code class="highlight"><c- n>B</c-></code> and <code class="highlight"><c- n>A</c-></code>.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.4.4" id="triangular-matrix-matrix-product-linalgalgsblas3trmm"><span class="secno">16.9.4.4. </span><span class="content">Triangular matrix-matrix product [linalg.algs.blas3.trmm]</span><a class="self-link" href="#triangular-matrix-matrix-product-linalgalgsblas3trmm"></a></h5>
   <p><em>[Note:</em> These functions correspond to the BLAS function <code class="highlight"><c- n>xTRMM</c-></code>.
--<em>end note]</em></p>
   <p>The following requirements apply to all functions in this section.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>,</p>
      <li data-md>
       <p><code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>E</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> (if applicable), and</p>
      <li data-md>
       <p><code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>E</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> (if applicable).</p>
     </ul>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>in_matrix_1_t</c-></code> either has unique layout,
or <code class="highlight"><c- n>layout_blas_packed</c-></code> layout.</p>
      <li data-md>
       <p><code class="highlight"><c- n>in_matrix_2_t</c-></code>, <code class="highlight"><c- n>in_matrix_3_t</c-></code> (if applicable), <code class="highlight"><c- n>out_matrix_t</c-></code>,
and <code class="highlight"><c- n>inout_matrix_t</c-></code> (if applicable) have unique layout.</p>
      <li data-md>
       <p>If <code class="highlight"><c- n>in_matrix_1_t</c-></code> has <code class="highlight"><c- n>layout_blas_packed</c-></code> layout, then the
layout’s <code class="highlight"><c- n>Triangle</c-></code> template argument has the same type as
the function’s <code class="highlight"><c- n>Triangle</c-></code> template argument.</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, and <code class="highlight"><c- n>E</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> (if applicable) equals 2.</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>For all <code class="highlight"><c- n>r</c-></code> in 0, 1, ..., <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> - 1, if neither <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>E</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>E</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> (if applicable).</p>
     </ul>
    <li data-md>
     <p><em>Remarks:</em></p>
     <ul>
      <li data-md>
       <p>The functions will only access the triangle of <code class="highlight"><c- n>A</c-></code> specified by
the <code class="highlight"><c- n>Triangle</c-></code> argument <code class="highlight"><c- n>t</c-></code>.</p>
      <li data-md>
       <p>If the <code class="highlight"><c- n>DiagonalStorage</c-></code> template argument has type <code class="highlight"><c- n>implicit_unit_diagonal_t</c-></code>, then the functions will not access the
diagonal of <code class="highlight"><c- n>A</c-></code>, and will assume that that the diagonal elements
of <code class="highlight"><c- n>A</c-></code> all equal one. <em>[Note:</em> This does not imply that the
function needs to be able to form an <code class="highlight"><c- n>element_type</c-></code> value equal to
one. --*end note]</p>
      <li data-md>
       <p><code class="highlight"><c- n>C</c-></code> and <code class="highlight"><c- n>E</c-></code> (if applicable) may refer to the same matrix.
If so, then they must have the same layout.</p>
     </ul>
   </ul>
   <p>The following requirements apply to all overloads of <code class="highlight"><c- n>triangular_matrix_left_product</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> (if applicable),</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, and</p>
      <li data-md>
       <p><code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> (if applicable).</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> (if applicable);</p>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>; and</p>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> (if applicable).</p>
     </ul>
    <li data-md>
     <p><em>Complexity:</em> The count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
is linear in <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> times <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> times <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
   </ul>
   <p>The following requirements apply to all overloads of <code class="highlight"><c- n>triangular_matrix_right_product</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> (if applicable),</p>
      <li data-md>
       <p><code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> (if applicable), and</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> (if applicable);</p>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> (if applicable); and</p>
      <li data-md>
       <p>if neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Complexity:</em> The count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
is linear in <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> times <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> times <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.4.4.1" id="overwriting-triangular-matrix-matrix-left-product-linalgalgsblas3trmmovleft"><span class="secno">16.9.4.4.1. </span><span class="content">Overwriting triangular matrix-matrix left product [linalg.algs.blas3.trmm.ov.left]</span><a class="self-link" href="#overwriting-triangular-matrix-matrix-left-product-linalgalgsblas3trmmovleft"></a></h6>
   <p>Not-in-place overwriting triangular matrix-matrix left product</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_left_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_left_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>C</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-></code> the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>*</c-> <c- n>B</c-><c- p>[</c-><c- n>k</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k</c-></code> such that <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code> and <code class="highlight"><c- n>d</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of the matrix <code class="highlight"><c- n>C</c-></code> the product of the matrices <code class="highlight"><c- n>A</c-></code> and <code class="highlight"><c- n>B</c-></code>.</p>
   </ul>
   <p>In-place overwriting triangular matrix-matrix left product</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_left_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_left_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>C</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-></code> the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>*</c-> <c- n>C</c-><c- p>[</c-><c- n>k</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k</c-></code> such that <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code> and <code class="highlight"><c- n>d</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Mandates:</em> If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>,
then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Effects:</em> Overwrites <code class="highlight"><c- n>C</c-></code> on output with the product of the matrices <code class="highlight"><c- n>A</c-></code> and <code class="highlight"><c- n>C</c-></code> (on input).</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.4.4.2" id="overwriting-triangular-matrix-matrix-right-product-linalgalgsblas3trmmovright"><span class="secno">16.9.4.4.2. </span><span class="content">Overwriting triangular matrix-matrix right product [linalg.algs.blas3.trmm.ov.right]</span><a class="self-link" href="#overwriting-triangular-matrix-matrix-right-product-linalgalgsblas3trmmovright"></a></h6>
   <p>Not-in-place overwriting triangular matrix-matrix right product</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_right_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_right_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>C</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-></code> the sum of <code class="highlight"><c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>*</c-> <c- n>A</c-><c- p>[</c-><c- n>k</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k</c-></code> such that <code class="highlight"><c- n>k</c-><c- p>,</c-><c- n>j</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code> and <code class="highlight"><c- n>d</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of the matrix <code class="highlight"><c- n>C</c-></code> the product of the matrices <code class="highlight"><c- n>B</c-></code> and <code class="highlight"><c- n>A</c-></code>.</p>
   </ul>
   <p>In-place overwriting triangular matrix-matrix right product</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_right_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_right_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>C</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-></code> the sum of <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>*</c-> <c- n>A</c-><c- p>[</c-><c- n>k</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k</c-></code> such that <code class="highlight"><c- n>k</c-><c- p>,</c-><c- n>j</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code> and <code class="highlight"><c- n>d</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Mandates:</em> If neither <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Effects:</em> Overwrites <code class="highlight"><c- n>C</c-></code> on output
with the product of the matrices <code class="highlight"><c- n>C</c-></code> (on input) and <code class="highlight"><c- n>A</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.4.4.3" id="updating-triangular-matrix-matrix-left-product-linalgalgsblas3trmmupleft"><span class="secno">16.9.4.4.3. </span><span class="content">Updating triangular matrix-matrix left product [linalg.algs.blas3.trmm.up.left]</span><a class="self-link" href="#updating-triangular-matrix-matrix-left-product-linalgalgsblas3trmmupleft"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_left_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_left_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>C</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-> <c- n>E</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> plus the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>*</c-> <c- n>B</c-><c- p>[</c-><c- n>k</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k</c-></code> such that <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code> and <code class="highlight"><c- n>d</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of the matrix <code class="highlight"><c- n>C</c-></code> on output,
the elementwise sum of <code class="highlight"><c- n>E</c-></code> and the product of the matrices <code class="highlight"><c- n>A</c-></code> and <code class="highlight"><c- n>B</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.4.4.4" id="updating-triangular-matrix-matrix-right-product-linalgalgsblas3trmmupright"><span class="secno">16.9.4.4.4. </span><span class="content">Updating triangular matrix-matrix right product [linalg.algs.blas3.trmm.up.right]</span><a class="self-link" href="#updating-triangular-matrix-matrix-right-product-linalgalgsblas3trmmupright"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_right_product</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_3_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_right_product</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>in_matrix_3_t</c-> <c- n>E</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>C</c-><c- p>);</c->
</pre>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>C</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-> <c- n>E</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> plus the sum of <code class="highlight"><c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>*</c-> <c- n>A</c-><c- p>[</c-><c- n>k</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k</c-></code> such that <code class="highlight"><c- n>k</c-><c- p>,</c-><c- n>j</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code> and in the triangle of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code> and <code class="highlight"><c- n>d</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of the matrix <code class="highlight"><c- n>C</c-></code> on output,
the elementwise sum of <code class="highlight"><c- n>E</c-></code> and the product of the matrices <code class="highlight"><c- n>B</c-></code> and <code class="highlight"><c- n>A</c-></code>.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.4.5" id="rank-k-update-of-a-symmetric-or-hermitian-matrix-linalgalgblas3rank-k"><span class="secno">16.9.4.5. </span><span class="content">Rank-k update of a symmetric or Hermitian matrix [linalg.alg.blas3.rank-k]</span><a class="self-link" href="#rank-k-update-of-a-symmetric-or-hermitian-matrix-linalgalgblas3rank-k"></a></h5>
   <p><em>[Note:</em> Users can achieve the effect of the <code class="highlight"><c- n>TRANS</c-></code> argument of these
BLAS functions, by applying <code class="highlight"><c- n>transposed</c-></code> or <code class="highlight"><c- n>conjugate_transposed</c-></code> to the input matrix. --<em>end note]</em></p>
   <ul>
    <li data-md>
     <p><em>Complexity:</em> For all algorithms in this Clause,
the count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
is linear in <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> times <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> times <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.4.5.1" id="rank-k-symmetric-matrix-update-linalgalgblas3rank-ksyrk"><span class="secno">16.9.4.5.1. </span><span class="content">Rank-k symmetric matrix update [linalg.alg.blas3.rank-k.syrk]</span><a class="self-link" href="#rank-k-symmetric-matrix-update-linalgalgblas3rank-ksyrk"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_rank_k_update</c-><c- p>(</c->
  <c- n>T</c-> <c- n>alpha</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_rank_k_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>T</c-> <c- n>alpha</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em></p>
   <p>These functions correspond to the BLAS function <code class="highlight"><c- n>xSYRK</c-></code>.</p>
   <p>They take a scaling factor <code class="highlight"><c- n>alpha</c-></code>, because it would be
impossible to express the update C = C - A A^T otherwise.
The scaling factor parameter is required
in order to avoid ambiguity with <code class="highlight"><c- n>ExecutionPolicy</c-></code>.</p>
   <p>--<em>end note]</em></p>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>C</c-></code> and in the triangle of <code class="highlight"><c- n>C</c-></code> specified by <code class="highlight"><c- n>t</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-> <c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> plus the sum of <code class="highlight"><c- n>alpha</c-> <c- o>*</c-> <c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>*</c-> <c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k</c-></code> such that <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, and</p>
      <li data-md>
       <p><code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2 and <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2.</p>
      <li data-md>
       <p><code class="highlight"><c- n>C</c-></code> either has unique layout, or <code class="highlight"><c- n>layout_blas_packed</c-></code> layout.</p>
      <li data-md>
       <p>If <code class="highlight"><c- n>C</c-></code> has <code class="highlight"><c- n>layout_blas_packed</c-></code> layout, then the layout’s <code class="highlight"><c- n>Triangle</c-></code> template argument has the same type as the function’s <code class="highlight"><c- n>Triangle</c-></code> template argument.</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Effects:</em></p>
     <ul>
      <li data-md>
       <p>Assigns to <code class="highlight"><c- n>C</c-></code> on output, the elementwise sum of <code class="highlight"><c- n>C</c-></code> on input
with <code class="highlight"><c- n>alpha</c-></code> times (the matrix product of <code class="highlight"><c- n>A</c-></code> and the nonconjugated transpose of <code class="highlight"><c- n>A</c-></code>).</p>
     </ul>
    <li data-md>
     <p><em>Remarks:</em> The functions will only access the triangle of <code class="highlight"><c- n>C</c-></code> specified by the <code class="highlight"><c- n>Triangle</c-></code> argument <code class="highlight"><c- n>t</c-></code>, and will assume for
indices <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> outside that triangle, that <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.4.5.2" id="rank-k-hermitian-matrix-update-linalgalgblas3rank-kherk"><span class="secno">16.9.4.5.2. </span><span class="content">Rank-k Hermitian matrix update [linalg.alg.blas3.rank-k.herk]</span><a class="self-link" href="#rank-k-hermitian-matrix-update-linalgalgblas3rank-kherk"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_rank_k_update</c-><c- p>(</c->
  <c- n>T</c-> <c- n>alpha</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>T</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_rank_k_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>T</c-> <c- n>alpha</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em></p>
   <p>These functions correspond to the BLAS function <code class="highlight"><c- n>xHERK</c-></code>.</p>
   <p>They take a scaling factor <code class="highlight"><c- n>alpha</c-></code>, because it would be
impossible to express the updates C = C - A A^T or C = C - A A^H
otherwise.
The scaling factor parameter is required
in order to avoid ambiguity with <code class="highlight"><c- n>ExecutionPolicy</c-></code>.</p>
   <p>--<em>end note]</em></p>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>C</c-></code> and in the triangle of <code class="highlight"><c- n>C</c-></code> specified by <code class="highlight"><c- n>t</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-> <c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> plus the sum of <code class="highlight"><c- n>alpha</c-> <c- o>*</c-> <c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>*</c-> <c- n>conj</c-><c- p>(</c-><c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>k</c-><c- p>])</c-></code> for all <code class="highlight"><c- n>k</c-></code> such that <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, and</p>
      <li data-md>
       <p><code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2 and <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2.</p>
      <li data-md>
       <p><code class="highlight"><c- n>C</c-></code> either has unique layout, or <code class="highlight"><c- n>layout_blas_packed</c-></code> layout.</p>
      <li data-md>
       <p>If <code class="highlight"><c- n>C</c-></code> has <code class="highlight"><c- n>layout_blas_packed</c-></code> layout, then the layout’s <code class="highlight"><c- n>Triangle</c-></code> template argument has the same type as the function’s <code class="highlight"><c- n>Triangle</c-></code> template argument.</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Effects:</em></p>
     <ul>
      <li data-md>
       <p>Assigns to <code class="highlight"><c- n>C</c-></code> on output, the elementwise
sum of <code class="highlight"><c- n>C</c-></code> on input with alpha times (the matrix product of <code class="highlight"><c- n>A</c-></code> and the conjugated transpose of <code class="highlight"><c- n>A</c-></code>).</p>
     </ul>
    <li data-md>
     <p><em>Remarks:</em> The functions will only access the triangle of <code class="highlight"><c- n>C</c-></code> specified by the <code class="highlight"><c- n>Triangle</c-></code> argument <code class="highlight"><c- n>t</c-></code>, and will assume for
indices <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> outside that triangle, that <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code>.</p>
   </ul>
   <h5 class="heading settled" data-level="16.9.4.6" id="rank-2k-update-of-a-symmetric-or-hermitian-matrix-linalgalgblas3rank2k"><span class="secno">16.9.4.6. </span><span class="content">Rank-2k update of a symmetric or Hermitian matrix [linalg.alg.blas3.rank2k]</span><a class="self-link" href="#rank-2k-update-of-a-symmetric-or-hermitian-matrix-linalgalgblas3rank2k"></a></h5>
   <p><em>[Note:</em> Users can achieve the effect of the <code class="highlight"><c- n>TRANS</c-></code> argument of these
BLAS functions, by applying <code class="highlight"><c- n>transposed</c-></code> or <code class="highlight"><c- n>conjugate_transposed</c-></code> to the input matrices. --<em>end note]</em></p>
   <ul>
    <li data-md>
     <p><em>Complexity:</em> The count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
is linear in <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> times <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> times <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.4.6.1" id="rank-2k-symmetric-matrix-update-linalgalgblas3rank2ksyr2k"><span class="secno">16.9.4.6.1. </span><span class="content">Rank-2k symmetric matrix update [linalg.alg.blas3.rank2k.syr2k]</span><a class="self-link" href="#rank-2k-symmetric-matrix-update-linalgalgblas3rank2ksyr2k"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_rank_2k_update</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>symmetric_matrix_rank_2k_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em> These functions correspond to the BLAS function <code class="highlight"><c- n>xSYR2K</c-></code>.
The BLAS "quick reference" has a typo; the "ALPHA" argument of <code class="highlight"><c- n>CSYR2K</c-></code> and <code class="highlight"><c- n>ZSYR2K</c-></code> should not be conjugated.  --<em>end note]</em></p>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>C</c-></code> and in the triangle of <code class="highlight"><c- n>C</c-></code> specified by <code class="highlight"><c- n>t</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-> <c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> plus the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k1</c-><c- p>]</c-> <c- o>*</c-> <c- n>B</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>k1</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k1</c-></code> such that <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k1</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code>,
plus the sum of <code class="highlight"><c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k2</c-><c- p>]</c-> <c- o>*</c-> <c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>k2</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>k2</c-></code> such that <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k2</c-></code> is in the domain of <code class="highlight"><c- n>B</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>,</p>
      <li data-md>
       <p><code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, and</p>
      <li data-md>
       <p><code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, and <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2.</p>
      <li data-md>
       <p><code class="highlight"><c- n>C</c-></code> either has unique layout, or <code class="highlight"><c- n>layout_blas_packed</c-></code> layout.</p>
      <li data-md>
       <p>If <code class="highlight"><c- n>C</c-></code> has <code class="highlight"><c- n>layout_blas_packed</c-></code> layout, then the layout’s <code class="highlight"><c- n>Triangle</c-></code> template argument has the same type as the function’s <code class="highlight"><c- n>Triangle</c-></code> template argument.</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to <code class="highlight"><c- n>C</c-></code> on output, the elementwise sum of <code class="highlight"><c- n>C</c-></code> on
input with (the matrix product of <code class="highlight"><c- n>A</c-></code> and the nonconjugated
transpose of <code class="highlight"><c- n>B</c-></code>) and (the matrix product of <code class="highlight"><c- n>B</c-></code> and the
nonconjugated transpose of <code class="highlight"><c- n>A</c-></code>.)</p>
    <li data-md>
     <p><em>Remarks:</em> The functions will only access the triangle of <code class="highlight"><c- n>C</c-></code> specified by the <code class="highlight"><c- n>Triangle</c-></code> argument <code class="highlight"><c- n>t</c-></code>, and will assume for
indices <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> outside that triangle, that <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code>.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.4.6.2" id="rank-2k-hermitian-matrix-update-linalgalgblas3rank2kher2k"><span class="secno">16.9.4.6.2. </span><span class="content">Rank-2k Hermitian matrix update [linalg.alg.blas3.rank2k.her2k]</span><a class="self-link" href="#rank-2k-hermitian-matrix-update-linalgalgblas3rank2kher2k"></a></h6>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_rank_2k_update</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>void</c-> <c- n>hermitian_matrix_rank_2k_update</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>C</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em> These functions correspond to the BLAS function <code class="highlight"><c- n>xHER2K</c-></code>.
--<em>end note]</em></p>
   <p>For <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> in the domain of <code class="highlight"><c- n>C</c-></code> and in the triangle of <code class="highlight"><c- n>C</c-></code> specified by <code class="highlight"><c- n>t</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>=</c-> <c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code> plus the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k1</c-><c- p>]</c-> <c- o>*</c-> <c- n>conj</c-><c- p>(</c-><c- n>B</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>k1</c-><c- p>])</c-></code> for all <code class="highlight"><c- n>k1</c-></code> such that <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k1</c-></code> is in the domain of <code class="highlight"><c- n>A</c-></code>,
plus the sum of <code class="highlight"><c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k2</c-><c- p>]</c-> <c- o>*</c-> <c- n>conj</c-><c- p>(</c-><c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>k2</c-><c- p>])</c-></code> for all <code class="highlight"><c- n>k2</c-></code> such that <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k2</c-></code> is in the domain of <code class="highlight"><c- n>B</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>,</p>
      <li data-md>
       <p><code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, and</p>
      <li data-md>
       <p><code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2, and <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2.</p>
      <li data-md>
       <p><code class="highlight"><c- n>C</c-></code> either has unique layout, or <code class="highlight"><c- n>layout_blas_packed</c-></code> layout.</p>
      <li data-md>
       <p>If <code class="highlight"><c- n>C</c-></code> has <code class="highlight"><c- n>layout_blas_packed</c-></code> layout, then the layout’s <code class="highlight"><c- n>Triangle</c-></code> template argument has the same type as the function’s <code class="highlight"><c- n>Triangle</c-></code> template argument.</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Effects:</em> Assigns to <code class="highlight"><c- n>C</c-></code> on output,
the elementwise sum of <code class="highlight"><c- n>C</c-></code> on input with
(the matrix product of <code class="highlight"><c- n>A</c-></code> and the conjugate transpose of <code class="highlight"><c- n>B</c-></code>) and
(the matrix product of <code class="highlight"><c- n>B</c-></code> and the conjugate transpose of <code class="highlight"><c- n>A</c-></code>.)</p>
    <li data-md>
     <p><em>Remarks:</em></p>
     <ul>
      <li data-md>
       <p>The functions will only access the triangle of <code class="highlight"><c- n>C</c-></code> specified by
the <code class="highlight"><c- n>Triangle</c-></code> argument <code class="highlight"><c- n>t</c-></code>.</p>
      <li data-md>
       <p>If <code class="highlight"><c- n>inout_matrix_t</c-><c- o>::</c-><c- n>element_type</c-></code> is <code class="highlight"><c- n>complex</c-><c- o>&lt;</c-><c- n>RC</c-><c- o>></c-></code> for some <code class="highlight"><c- n>RC</c-></code>,
then the functions will assume for indices <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> outside that
triangle, that <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code> equals <code class="highlight"><c- n>conj</c-><c- p>(</c-><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>])</c-></code>.  Otherwise, the
functions will assume that <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code> equals <code class="highlight"><c- n>C</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-></code>.</p>
     </ul>
   </ul>
   <h5 class="heading settled" data-level="16.9.4.7" id="solve-multiple-triangular-linear-systems-linalgalgblas3trsm"><span class="secno">16.9.4.7. </span><span class="content">Solve multiple triangular linear systems [linalg.alg.blas3.trsm]</span><a class="self-link" href="#solve-multiple-triangular-linear-systems-linalgalgblas3trsm"></a></h5>
   <p><em>[Note:</em> These functions correspond to the BLAS function <code class="highlight"><c- n>xTRSM</c-></code>.  The
Reference BLAS does not have a <code class="highlight"><c- n>xTPSM</c-></code> function. --<em>end note]</em></p>
   <p>The following requirements apply to all functions in this section.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em></p>
     <ul>
      <li data-md>
       <p>For all <code class="highlight"><c- n>r</c-></code> in 0, 1, ..., <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> - 1, <code class="highlight"><c- n>X</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> (if applicable); and</p>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Constraints:</em></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2 and <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2;</p>
      <li data-md>
       <p><code class="highlight"><c- n>X</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> equals 2 (if applicable);</p>
      <li data-md>
       <p><code class="highlight"><c- n>in_matrix_1_t</c-></code> either has unique layout, or <code class="highlight"><c- n>layout_blas_packed</c-></code> layout;</p>
      <li data-md>
       <p><code class="highlight"><c- n>in_matrix_2_t</c-></code> has unique layout (if applicable);</p>
      <li data-md>
       <p><code class="highlight"><c- n>out_matrix_t</c-></code> has unique layout;</p>
      <li data-md>
       <p><code class="highlight"><c- n>inout_matrix_t</c-></code> has unique layout (if applicable);</p>
      <li data-md>
       <p>if <code class="highlight"><c- n>r</c-><c- p>,</c-><c- n>j</c-></code> is in the domain of <code class="highlight"><c- n>X</c-></code> and <code class="highlight"><c- n>B</c-></code>, then the expression <code class="highlight"><c- n>X</c-><c- p>(</c-><c- n>r</c-><c- p>,</c-><c- n>j</c-><c- p>)</c-> <c- o>=</c-> <c- n>B</c-><c- p>(</c-><c- n>r</c-><c- p>,</c-><c- n>j</c-><c- p>)</c-></code> is well formed (if applicable); and</p>
      <li data-md>
       <p>if <code class="highlight"><c- n>DiagonalStorage</c-></code> is <code class="highlight"><c- n>explicit_diagonal_t</c-></code>,
and <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>j</c-></code> is in the domain of <code class="highlight"><c- n>X</c-></code>,
then the expression <code class="highlight"><c- n>X</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>/=</c-> <c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code> is well formed (if applicable).</p>
     </ul>
    <li data-md>
     <p><em>Mandates:</em></p>
     <ul>
      <li data-md>
       <p>For all <code class="highlight"><c- n>r</c-></code> in 0, 1, ..., <code class="highlight"><c- n>X</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> - 1, if neither <code class="highlight"><c- n>X</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>X</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-><c- p>)</c-></code> (if applicable).</p>
      <li data-md>
       <p>If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
     </ul>
    <li data-md>
     <p><em>Remarks:</em></p>
     <ul>
      <li data-md>
       <p>The functions will only access the triangle of <code class="highlight"><c- n>A</c-></code> specified by
the <code class="highlight"><c- n>Triangle</c-></code> argument <code class="highlight"><c- n>t</c-></code>.</p>
      <li data-md>
       <p>If the <code class="highlight"><c- n>DiagonalStorage</c-></code> template argument has type <code class="highlight"><c- n>implicit_unit_diagonal_t</c-></code>, then the functions will not access the
diagonal of <code class="highlight"><c- n>A</c-></code>, and will assume that that the diagonal elements
of <code class="highlight"><c- n>A</c-></code> all equal one. <em>[Note:</em> This does not imply that the
function needs to be able to form an <code class="highlight"><c- n>element_type</c-></code> value equal to
one. --*end note]</p>
     </ul>
   </ul>
   <h6 class="heading settled" data-level="16.9.4.7.1" id="solve-multiple-triangular-linear-systems-with-triangular-matrix-on-the-left-linalgalgblas3trsmleft"><span class="secno">16.9.4.7.1. </span><span class="content">Solve multiple triangular linear systems with triangular matrix on the left [linalg.alg.blas3.trsm.left]</span><a class="self-link" href="#solve-multiple-triangular-linear-systems-with-triangular-matrix-on-the-left-linalgalgblas3trsmleft"></a></h6>
   <ul>
    <li data-md>
     <p><em>Complexity:</em> The count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
is linear in <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> times <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> times <code class="highlight"><c- n>X</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
   </ul>
   <p>Not-in-place left solve of multiple triangular systems</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_matrix_left_solve</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>X</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_matrix_left_solve</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>X</c-><c- p>);</c->
</pre>
   <p>If <code class="highlight"><c- n>DiagonalStorage</c-></code> is <code class="highlight"><c- n>explicit_diagonal_t</c-></code>,
then for <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k</c-></code> in the domain of <code class="highlight"><c- n>X</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>X</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>=</c-> <c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>-</c-> <c- n>s</c-> <c- o>/</c-> <c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code>,
where <code class="highlight"><c- n>s</c-></code> is the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>X</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> in the subset of the domain of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code> and <code class="highlight"><c- n>d</c-></code>.</p>
   <p>If <code class="highlight"><c- n>DiagonalStorage</c-></code> is <code class="highlight"><c- n>implicit_unit_diagonal_t</c-></code>,
then for <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k</c-></code> in the domain of <code class="highlight"><c- n>X</c-></code>,
then the mathematical expression for the algorithm is <code class="highlight"><c- n>X</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>=</c-> <c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>-</c-> <c- n>s</c-></code>,
where <code class="highlight"><c- n>s</c-></code> is the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>X</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> in the subset of the domain of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code> and <code class="highlight"><c- n>d</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Mandates:</em> If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of <code class="highlight"><c- n>X</c-></code> the result of solving the triangular linear system(s) AX=B for X.</p>
   </ul>
   <p>In-place left solve of multiple triangular systems</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_matrix_left_solve</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>B</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_matrix_left_solve</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>B</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em></p>
   <p>This algorithm makes it possible to compute factorizations like
Cholesky and LU in place.</p>
   <p>Performing triangular solve in place hinders parallelization.
However, other <code class="highlight"><c- n>ExecutionPolicy</c-></code>-specific optimizations,
such as vectorization, are still possible.
This is why the <code class="highlight"><c- n>ExecutionPolicy</c-></code> overload exists.</p>
   <p>--<em>end note]</em></p>
   <p>If <code class="highlight"><c- n>DiagonalStorage</c-></code> is <code class="highlight"><c- n>explicit_diagonal_t</c-></code>,
then for <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k</c-></code> in the domain of <code class="highlight"><c- n>B</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>=</c-> <c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>-</c-> <c- n>s</c-> <c- o>/</c-> <c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code>,
where <code class="highlight"><c- n>s</c-></code> is the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>B</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> in the subset of the domain of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code> and <code class="highlight"><c- n>d</c-></code>.</p>
   <p>If <code class="highlight"><c- n>DiagonalStorage</c-></code> is <code class="highlight"><c- n>implicit_unit_diagonal_t</c-></code>,
then for <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k</c-></code> in the domain of <code class="highlight"><c- n>B</c-></code>,
then the mathematical expression for the algorithm is <code class="highlight"><c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>=</c-> <c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>-</c-> <c- n>s</c-></code>,
where <code class="highlight"><c- n>s</c-></code> is the sum of <code class="highlight"><c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>B</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> in the subset of the domain of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code> and <code class="highlight"><c- n>d</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Mandates:</em> If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Effects:</em> Overwrites <code class="highlight"><c- n>B</c-></code> with the result of solving the triangular
 linear system(s) AX=B for X.</p>
   </ul>
   <h6 class="heading settled" data-level="16.9.4.7.2" id="solve-multiple-triangular-linear-systems-with-triangular-matrix-on-the-right-linalgalgblas3trsmright"><span class="secno">16.9.4.7.2. </span><span class="content">Solve multiple triangular linear systems with triangular matrix on the right [linalg.alg.blas3.trsm.right]</span><a class="self-link" href="#solve-multiple-triangular-linear-systems-with-triangular-matrix-on-the-right-linalgalgblas3trsmright"></a></h6>
   <ul>
    <li data-md>
     <p><em>Complexity:</em> The count of <code class="highlight"><c- n>mdspan</c-></code> array accesses and arithmetic operations
is linear in <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> times <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> times <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
   </ul>
   <p>Not-in-place right solve of multiple triangular systems</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_matrix_right_solve</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>X</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_matrix_right_solve</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>in_matrix_2_t</c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_t</c-> <c- n>X</c-><c- p>);</c->
</pre>
   <p>If <code class="highlight"><c- n>DiagonalStorage</c-></code> is <code class="highlight"><c- n>explicit_diagonal_t</c-></code>,
then for <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k</c-></code> in the domain of <code class="highlight"><c- n>X</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>X</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>=</c-> <c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>-</c-> <c- n>s</c-> <c- o>/</c-> <c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code>,
where <code class="highlight"><c- n>s</c-></code> is the sum of <code class="highlight"><c- n>X</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> in the subset of the domain of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code> and <code class="highlight"><c- n>d</c-></code>.</p>
   <p>If <code class="highlight"><c- n>DiagonalStorage</c-></code> is <code class="highlight"><c- n>implicit_unit_diagonal_t</c-></code>,
then for <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k</c-></code> in the domain of <code class="highlight"><c- n>X</c-></code>,
then the mathematical expression for the algorithm is <code class="highlight"><c- n>X</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>=</c-> <c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>-</c-> <c- n>s</c-></code>,
where <code class="highlight"><c- n>s</c-></code> is the sum of <code class="highlight"><c- n>X</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> in the subset of the domain of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code> and <code class="highlight"><c- n>d</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Mandates:</em> If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Effects:</em> Assigns to the elements of <code class="highlight"><c- n>X</c-></code> the result of solving the triangular linear system(s) XA=B for X.</p>
   </ul>
   <p>In-place right solve of multiple triangular systems</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_matrix_right_solve</c-><c- p>(</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>B</c-><c- p>);</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ExecutionPolicy</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>DiagonalStorage</c-><c- p>,</c->
         <c- n>class</c-> <c- n>inout_matrix_t</c-><c- o>></c->
<c- b>void</c-> <c- n>triangular_matrix_matrix_right_solve</c-><c- p>(</c->
  <c- n>ExecutionPolicy</c-><c- o>&amp;&amp;</c-> <c- n>exec</c-><c- p>,</c->
  <c- n>in_matrix_1_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>DiagonalStorage</c-> <c- n>d</c-><c- p>,</c->
  <c- n>inout_matrix_t</c-> <c- n>B</c-><c- p>);</c->
</pre>
   <p><em>[Note:</em></p>
   <p>This algorithm makes it possible to compute factorizations like
Cholesky and LU in place.</p>
   <p>Performing triangular solve in place hinders parallelization.
However, other <code class="highlight"><c- n>ExecutionPolicy</c-></code>-specific optimizations,
such as vectorization, are still possible.
This is why the <code class="highlight"><c- n>ExecutionPolicy</c-></code> overload exists.</p>
   <p>--<em>end note]</em></p>
   <p>If <code class="highlight"><c- n>DiagonalStorage</c-></code> is <code class="highlight"><c- n>explicit_diagonal_t</c-></code>,
then for <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k</c-></code> in the domain of <code class="highlight"><c- n>B</c-></code>,
the mathematical expression for the algorithm is <code class="highlight"><c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>=</c-> <c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>-</c-> <c- n>s</c-> <c- o>/</c-> <c- n>A</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>i</c-><c- p>]</c-></code>,
where <code class="highlight"><c- n>s</c-></code> is the sum of <code class="highlight"><c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> in the subset of the domain of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code> and <code class="highlight"><c- n>d</c-></code>.</p>
   <p>If <code class="highlight"><c- n>DiagonalStorage</c-></code> is <code class="highlight"><c- n>implicit_unit_diagonal_t</c-></code>,
then for <code class="highlight"><c- n>i</c-><c- p>,</c-><c- n>k</c-></code> in the domain of <code class="highlight"><c- n>B</c-></code>,
then the mathematical expression for the algorithm is <code class="highlight"><c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>=</c-> <c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-> <c- o>-</c-> <c- n>s</c-></code>,
where <code class="highlight"><c- n>s</c-></code> is the sum of <code class="highlight"><c- n>B</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>]</c-> <c- o>*</c-> <c- n>A</c-><c- p>[</c-><c- n>j</c-><c- p>,</c-><c- n>k</c-><c- p>]</c-></code> for all <code class="highlight"><c- n>j</c-></code> not equal to <code class="highlight"><c- n>i</c-></code> in the subset of the domain of <code class="highlight"><c- n>A</c-></code> specified by <code class="highlight"><c- n>t</c-></code> and <code class="highlight"><c- n>d</c-></code>.</p>
   <ul>
    <li data-md>
     <p><em>Preconditions:</em> <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Mandates:</em> If neither <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p><em>Effects:</em> Overwrites <code class="highlight"><c- n>B</c-></code> with the result of solving the triangular
 linear system(s) XA=B for X.</p>
   </ul>
   <h2 class="heading settled" data-level="17" id="examples"><span class="secno">17. </span><span class="content">Examples</span><a class="self-link" href="#examples"></a></h2>
   <h3 class="heading settled" data-level="17.1" id="cholesky-factorization"><span class="secno">17.1. </span><span class="content">Cholesky factorization</span><a class="self-link" href="#cholesky-factorization"></a></h3>
   <p>This example shows how to compute the Cholesky factorization of a real
symmetric positive definite matrix A stored as an <code class="highlight"><c- n>mdspan</c-></code> with a
unique non-packed layout.  The algorithm imitates <code class="highlight"><c- n>DPOTRF2</c-></code> in LAPACK
3.9.0.  If <code class="highlight"><c- n>Triangle</c-></code> is <code class="highlight"><c- n>upper_triangle_t</c-></code>, then it computes the
Cholesky factorization A = U^T U.  Otherwise, it computes the Cholesky
factorization A = L L^T.  The function returns 0 if success, else k+1
if row/column k has a zero or NaN (not a number) diagonal entry.</p>
<pre class="language-c++ highlight"><c- cp>#include</c-> &lt;linalg>
<c- cp>#include</c-> &lt;cmath>

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- o>></c->
<c- b>int</c-> <c- n>cholesky_factor</c-><c- p>(</c-><c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c-> <c- n>Triangle</c-> <c- n>t</c-><c- p>)</c->
<c- p>{</c->
  <c- n>using</c-> <c- n>element_type</c-> <c- o>=</c-> <c- n>typename</c-> <c- n>inout_matrix_t</c-><c- o>::</c-><c- n>element_type</c-><c- p>;</c->
  <c- n>constexpr</c-> <c- n>element_type</c-> <c- n>ZERO</c-> <c- p>{};</c->
  <c- n>constexpr</c-> <c- n>element_type</c-> <c- n>ONE</c-> <c- p>(</c-><c- mf>1.0</c-><c- p>);</c->
  <c- k>const</c-> <c- k>auto</c-> <c- n>n</c-> <c- o>=</c-> <c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>);</c->

  <c- k>if</c-> <c- p>(</c-><c- n>n</c-> <c- o>==</c-> <c- mi>0</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- mi>0</c-><c- p>;</c->
  <c- p>}</c->
  <c- k>else</c-> <c- k>if</c-> <c- p>(</c-><c- n>n</c-> <c- o>==</c-> <c- mi>1</c-><c- p>)</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- n>A</c-><c- p>[</c-><c- mi>0</c-><c- p>,</c-><c- mi>0</c-><c- p>]</c-> <c- o>&lt;=</c-> <c- n>ZERO</c-> <c- o>||</c-> <c- n>isnan</c-><c- p>(</c-><c- n>A</c-><c- p>[</c-><c- mi>0</c-><c- p>,</c-><c- mi>0</c-><c- p>]))</c-> <c- p>{</c->
      <c- k>return</c-> <c- mi>1</c-><c- p>;</c->
    <c- p>}</c->
    <c- n>A</c-><c- p>[</c-><c- mi>0</c-><c- p>,</c-><c- mi>0</c-><c- p>]</c-> <c- o>=</c-> <c- n>sqrt</c-><c- p>(</c-><c- n>A</c-><c- p>[</c-><c- mi>0</c-><c- p>,</c-><c- mi>0</c-><c- p>]);</c->
  <c- p>}</c->
  <c- k>else</c-> <c- p>{</c->
    <c- c1>// Partition A into [A11, A12,</c->
    <c- c1>//                   A21, A22],</c->
    <c- c1>// where A21 is the transpose of A12.</c->
    <c- k>const</c-> <c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>n1</c-> <c- o>=</c-> <c- n>n</c-> <c- o>/</c-> <c- mi>2</c-><c- p>;</c->
    <c- k>const</c-> <c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>n2</c-> <c- o>=</c-> <c- n>n</c-> <c- o>-</c-> <c- n>n1</c-><c- p>;</c->
    <c- k>auto</c-> <c- n>A11</c-> <c- o>=</c-> <c- n>submdspan</c-><c- p>(</c-><c- n>A</c-><c- p>,</c-> <c- n>pair</c-><c- p>{</c-><c- mi>0</c-><c- p>,</c-> <c- n>n1</c-><c- p>},</c-> <c- n>pair</c-><c- p>{</c-><c- mi>0</c-><c- p>,</c-> <c- n>n1</c-><c- p>});</c->
    <c- k>auto</c-> <c- n>A22</c-> <c- o>=</c-> <c- n>submdspan</c-><c- p>(</c-><c- n>A</c-><c- p>,</c-> <c- n>pair</c-><c- p>{</c-><c- n>n1</c-><c- p>,</c-> <c- n>n</c-><c- p>},</c-> <c- n>pair</c-><c- p>{</c-><c- n>n1</c-><c- p>,</c-> <c- n>n</c-><c- p>});</c->

    <c- c1>// Factor A11</c->
    <c- k>const</c-> <c- b>int</c-> <c- n>info1</c-> <c- o>=</c-> <c- n>cholesky_factor</c-><c- p>(</c-><c- n>A11</c-><c- p>,</c-> <c- n>t</c-><c- p>);</c->
    <c- k>if</c-> <c- p>(</c-><c- n>info1</c-> <c- o>!=</c-> <c- mi>0</c-><c- p>)</c-> <c- p>{</c->
      <c- k>return</c-> <c- n>info1</c-><c- p>;</c->
    <c- p>}</c->

    <c- n>using</c-> <c- n>std</c-><c- o>::</c-><c- n>linalg</c-><c- o>::</c-><c- n>symmetric_matrix_rank_k_update</c-><c- p>;</c->
    <c- n>using</c-> <c- n>std</c-><c- o>::</c-><c- n>linalg</c-><c- o>::</c-><c- n>transposed</c-><c- p>;</c->
    <c- k>if</c-> <c- nf>constexpr</c-> <c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>is_same_v</c-><c- o>&lt;</c-><c- n>Triangle</c-><c- p>,</c-> <c- n>upper_triangle_t</c-><c- o>></c-><c- p>)</c-> <c- p>{</c->
      <c- c1>// Update and scale A12</c->
      <c- k>auto</c-> <c- n>A12</c-> <c- o>=</c-> <c- n>submdspan</c-><c- p>(</c-><c- n>A</c-><c- p>,</c-> <c- n>pair</c-><c- p>{</c-><c- mi>0</c-><c- p>,</c-> <c- n>n1</c-><c- p>},</c-> <c- n>pair</c-><c- p>{</c-><c- n>n1</c-><c- p>,</c-> <c- n>n</c-><c- p>});</c->
      <c- n>using</c-> <c- n>std</c-><c- o>::</c-><c- n>linalg</c-><c- o>::</c-><c- n>triangular_matrix_matrix_left_solve</c-><c- p>;</c->
      <c- n>triangular_matrix_matrix_left_solve</c-><c- p>(</c-><c- n>transposed</c-><c- p>(</c-><c- n>A11</c-><c- p>),</c->
        <c- n>upper_triangle</c-><c- p>,</c-> <c- n>explicit_diagonal</c-><c- p>,</c-> <c- n>A12</c-><c- p>);</c->
      <c- c1>// A22 = A22 - A12^T * A12</c->
      <c- n>symmetric_matrix_rank_k_update</c-><c- p>(</c-><c- o>-</c-><c- n>ONE</c-><c- p>,</c-> <c- n>transposed</c-><c- p>(</c-><c- n>A12</c-><c- p>),</c->
                                      <c- n>A22</c-><c- p>,</c-> <c- n>t</c-><c- p>);</c->
    <c- p>}</c->
    <c- k>else</c-> <c- p>{</c->
      <c- c1>//</c->
      <c- c1>// Compute the Cholesky factorization A = L * L^T</c->
      <c- c1>//</c->
      <c- c1>// Update and scale A21</c->
      <c- k>auto</c-> <c- n>A21</c-> <c- o>=</c-> <c- n>submdspan</c-><c- p>(</c-><c- n>A</c-><c- p>,</c-> <c- n>pair</c-><c- p>{</c-><c- n>n1</c-><c- p>,</c-> <c- n>n</c-><c- p>},</c-> <c- n>pair</c-><c- p>{</c-><c- mi>0</c-><c- p>,</c-> <c- n>n1</c-><c- p>});</c->
      <c- n>using</c-> <c- n>std</c-><c- o>::</c-><c- n>linalg</c-><c- o>::</c-><c- n>triangular_matrix_matrix_right_solve</c-><c- p>;</c->
      <c- n>triangular_matrix_matrix_right_solve</c-><c- p>(</c-><c- n>transposed</c-><c- p>(</c-><c- n>A11</c-><c- p>),</c->
        <c- n>lower_triangle</c-><c- p>,</c-> <c- n>explicit_diagonal</c-><c- p>,</c-> <c- n>A21</c-><c- p>);</c->
      <c- c1>// A22 = A22 - A21 * A21^T</c->
      <c- n>symmetric_matrix_rank_k_update</c-><c- p>(</c-><c- o>-</c-><c- n>ONE</c-><c- p>,</c-> <c- n>A21</c-><c- p>,</c-> <c- n>A22</c-><c- p>,</c-> <c- n>t</c-><c- p>);</c->
    <c- p>}</c->

    <c- c1>// Factor A22</c->
    <c- k>const</c-> <c- b>int</c-> <c- n>info2</c-> <c- o>=</c-> <c- n>cholesky_factor</c-><c- p>(</c-><c- n>A22</c-><c- p>,</c-> <c- n>t</c-><c- p>);</c->
    <c- k>if</c-> <c- p>(</c-><c- n>info2</c-> <c- o>!=</c-> <c- mi>0</c-><c- p>)</c-> <c- p>{</c->
      <c- k>return</c-> <c- n>info2</c-> <c- o>+</c-> <c- n>n1</c-><c- p>;</c->
    <c- p>}</c->
  <c- p>}</c->
<c- p>}</c->
</pre>
   <h3 class="heading settled" data-level="17.2" id="solve-linear-system-using-cholesky-factorization"><span class="secno">17.2. </span><span class="content">Solve linear system using Cholesky factorization</span><a class="self-link" href="#solve-linear-system-using-cholesky-factorization"></a></h3>
   <p>This example shows how to solve a symmetric positive definite linear
system Ax=b, using the Cholesky factorization computed in the previous
example in-place in the matrix <code class="highlight"><c- n>A</c-></code>.  The example assumes that <code class="highlight"><c- n>cholesky_factor</c-><c- p>(</c-><c- n>A</c-><c- p>,</c-> <c- n>t</c-><c- p>)</c-></code> returned 0, indicating no zero or NaN pivots.</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>Triangle</c-><c- p>,</c->
         <c- n>class</c-> <c- n>in_vector_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_vector_t</c-><c- o>></c->
<c- b>void</c-> <c- n>cholesky_solve</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>Triangle</c-> <c- n>t</c-><c- p>,</c->
  <c- n>in_vector_t</c-> <c- n>b</c-><c- p>,</c->
  <c- n>out_vector_t</c-> <c- n>x</c-><c- p>)</c->
<c- p>{</c->
  <c- n>using</c-> <c- n>std</c-><c- o>::</c-><c- n>linalg</c-><c- o>::</c-><c- n>transposed</c-><c- p>;</c->
  <c- n>using</c-> <c- n>std</c-><c- o>::</c-><c- n>linalg</c-><c- o>::</c-><c- n>triangular_matrix_vector_solve</c-><c- p>;</c->

  <c- k>if</c-> <c- nf>constexpr</c-> <c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>is_same_v</c-><c- o>&lt;</c-><c- n>Triangle</c-><c- p>,</c-> <c- n>upper_triangle_t</c-><c- o>></c-><c- p>)</c-> <c- p>{</c->
    <c- c1>// Solve Ax=b where A = U^T U</c->
    <c- c1>//</c->
    <c- c1>// Solve U^T c = b, using x to store c.</c->
    <c- n>triangular_matrix_vector_solve</c-><c- p>(</c-><c- n>transposed</c-><c- p>(</c-><c- n>A</c-><c- p>),</c-> <c- n>t</c-><c- p>,</c->
                                   <c- n>explicit_diagonal</c-><c- p>,</c-> <c- n>b</c-><c- p>,</c-> <c- n>x</c-><c- p>);</c->
    <c- c1>// Solve U x = c, overwriting x with result.</c->
    <c- n>triangular_matrix_vector_solve</c-><c- p>(</c-><c- n>A</c-><c- p>,</c-> <c- n>t</c-><c- p>,</c-> <c- n>explicit_diagonal</c-><c- p>,</c-> <c- n>x</c-><c- p>);</c->
  <c- p>}</c->
  <c- k>else</c-> <c- p>{</c->
    <c- c1>// Solve Ax=b where A = L L^T</c->
    <c- c1>//</c->
    <c- c1>// Solve L c = b, using x to store c.</c->
    <c- n>triangular_matrix_vector_solve</c-><c- p>(</c-><c- n>A</c-><c- p>,</c-> <c- n>t</c-><c- p>,</c-> <c- n>explicit_diagonal</c-><c- p>,</c-> <c- n>b</c-><c- p>,</c-> <c- n>x</c-><c- p>);</c->
    <c- c1>// Solve L^T x = c, overwriting x with result.</c->
    <c- n>triangular_matrix_vector_solve</c-><c- p>(</c-><c- n>transposed</c-><c- p>(</c-><c- n>A</c-><c- p>),</c-> <c- n>t</c-><c- p>,</c->
                                   <c- n>explicit_diagonal</c-><c- p>,</c-> <c- n>x</c-><c- p>);</c->
  <c- p>}</c->
<c- p>}</c->
</pre>
   <h3 class="heading settled" data-level="17.3" id="compute-qr-factorization-of-a-tall-skinny-matrix"><span class="secno">17.3. </span><span class="content">Compute QR factorization of a tall skinny matrix</span><a class="self-link" href="#compute-qr-factorization-of-a-tall-skinny-matrix"></a></h3>
   <p>This example shows how to compute the QR factorization of a "tall and
skinny" matrix <code class="highlight"><c- n>V</c-></code>, using a cache-blocked algorithm based on rank-k
symmetric matrix update and Cholesky factorization.  "Tall and skinny"
means that the matrix has many more rows than columns.</p>
<pre class="language-c++ highlight"><c- c1>// Compute QR factorization A = Q R, with A storing Q.</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>inout_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_t</c-><c- o>></c->
<c- b>int</c-> <c- n>cholesky_tsqr_one_step</c-><c- p>(</c->
  <c- n>inout_matrix_t</c-> <c- n>A</c-><c- p>,</c-> <c- c1>// A on input, Q on output</c->
  <c- n>out_matrix_t</c-> <c- n>R</c-><c- p>)</c->
<c- p>{</c->
  <c- c1>// One might use cache size, sizeof(element_type), and A.extent(1)</c->
  <c- c1>// to pick the number of rows per block.  For now, we just pick</c->
  <c- c1>// some constant.</c->
  <c- n>constexpr</c-> <c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>max_num_rows_per_block</c-> <c- o>=</c-> <c- mi>500</c-><c- p>;</c->

  <c- n>using</c-> <c- n>R_element_type</c-> <c- o>=</c-> <c- n>typename</c-> <c- n>out_matrix_t</c-><c- o>::</c-><c- n>element_type</c-><c- p>;</c->
  <c- n>constexpr</c-> <c- n>R_element_type</c-> <c- n>ZERO</c-> <c- p>{};</c->
  <c- k>for</c-><c- p>(</c-><c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>&lt;</c-> <c- n>R</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>);</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c-> <c- p>{</c->
    <c- k>for</c-><c- p>(</c-><c- n>extents</c-><c- o>&lt;>::</c-><c- n>size_type</c-> <c- n>j</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>j</c-> <c- o>&lt;</c-> <c- n>R</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>);</c-> <c- o>++</c-><c- n>j</c-><c- p>)</c-> <c- p>{</c->
      <c- n>R</c-><c- p>[</c-><c- mi>0</c-><c- p>,</c-><c- mi>0</c-><c- p>]</c-> <c- o>=</c-> <c- n>ZERO</c-><c- p>;</c->
    <c- p>}</c->
  <c- p>}</c->

  <c- c1>// Cache-blocked version of R = R + A^T * A.</c->
  <c- k>const</c-> <c- k>auto</c-> <c- n>num_rows</c-> <c- o>=</c-> <c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>);</c->
  <c- k>auto</c-> <c- n>rest_num_rows</c-> <c- o>=</c-> <c- n>num_rows</c-><c- p>;</c->
  <c- k>auto</c-> <c- n>A_rest</c-> <c- o>=</c-> <c- n>A</c-><c- p>;</c->
  <c- k>while</c-><c- p>(</c-><c- n>A_rest</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-> <c- o>></c-> <c- mi>0</c-><c- p>)</c-> <c- p>{</c->
    <c- k>const</c-> <c- n>ptrdiff</c-> <c- n>num_rows_per_block</c-> <c- o>=</c->
      <c- n>min</c-><c- p>(</c-><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>),</c-> <c- n>max_num_rows_per_block</c-><c- p>);</c->
    <c- k>auto</c-> <c- n>A_cur</c-> <c- o>=</c-> <c- n>submdspan</c-><c- p>(</c-><c- n>A_rest</c-><c- p>,</c-> <c- n>pair</c-><c- p>{</c-><c- mi>0</c-><c- p>,</c-> <c- n>num_rows_per_block</c-><c- p>},</c-> <c- n>full_extent</c-><c- p>);</c->
    <c- n>A_rest</c-> <c- o>=</c-> <c- n>submdspan</c-><c- p>(</c-><c- n>A_rest</c-><c- p>,</c->
      <c- n>pair</c-><c- p>{</c-><c- n>num_rows_per_block</c-><c- p>,</c-> <c- n>A_rest</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)},</c-> <c- n>full_extent</c-><c- p>);</c->
    <c- c1>// R = R + A_cur^T * A_cur</c->
    <c- n>using</c-> <c- n>std</c-><c- o>::</c-><c- n>linalg</c-><c- o>::</c-><c- n>symmetric_matrix_rank_k_update</c-><c- p>;</c->
    <c- n>constexpr</c-> <c- n>R_element_type</c-> <c- n>ONE</c-><c- p>(</c-><c- mf>1.0</c-><c- p>);</c->
    <c- n>symmetric_matrix_rank_k_update</c-><c- p>(</c-><c- n>ONE</c-><c- p>,</c-> <c- n>transposed</c-><c- p>(</c-><c- n>A_cur</c-><c- p>),</c->
                                   <c- n>R</c-><c- p>,</c-> <c- n>upper_triangle</c-><c- p>);</c->
  <c- p>}</c->

  <c- k>const</c-> <c- b>int</c-> <c- n>info</c-> <c- o>=</c-> <c- n>cholesky_factor</c-><c- p>(</c-><c- n>R</c-><c- p>,</c-> <c- n>upper_triangle</c-><c- p>);</c->
  <c- k>if</c-><c- p>(</c-><c- n>info</c-> <c- o>!=</c-> <c- mi>0</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>info</c-><c- p>;</c->
  <c- p>}</c->
  <c- n>using</c-> <c- n>std</c-><c- o>::</c-><c- n>linalg</c-><c- o>::</c-><c- n>triangular_matrix_matrix_left_solve</c-><c- p>;</c->
  <c- n>triangular_matrix_matrix_left_solve</c-><c- p>(</c-><c- n>R</c-><c- p>,</c-> <c- n>upper_triangle</c-><c- p>,</c-> <c- n>A</c-><c- p>);</c->
  <c- k>return</c-> <c- n>info</c-><c- p>;</c->
<c- p>}</c->

<c- c1>// Compute QR factorization A = Q R.  Use R_tmp as temporary R factor</c->
<c- c1>// storage for iterative refinement.</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>in_matrix_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_1_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_2_t</c-><c- p>,</c->
         <c- n>class</c-> <c- n>out_matrix_3_t</c-><c- o>></c->
<c- b>int</c-> <c- n>cholesky_tsqr</c-><c- p>(</c->
  <c- n>in_matrix_t</c-> <c- n>A</c-><c- p>,</c->
  <c- n>out_matrix_1_t</c-> <c- n>Q</c-><c- p>,</c->
  <c- n>out_matrix_2_t</c-> <c- n>R_tmp</c-><c- p>,</c->
  <c- n>out_matrix_3_t</c-> <c- n>R</c-><c- p>)</c->
<c- p>{</c->
  <c- n>assert</c-><c- p>(</c-><c- n>R</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-> <c- o>==</c-> <c- n>R</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>));</c->
  <c- n>assert</c-><c- p>(</c-><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-> <c- o>==</c-> <c- n>R</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>));</c->
  <c- n>assert</c-><c- p>(</c-><c- n>R_tmp</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-> <c- o>==</c-> <c- n>R_tmp</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>));</c->
  <c- n>assert</c-><c- p>(</c-><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-> <c- o>==</c-> <c- n>Q</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>));</c->
  <c- n>assert</c-><c- p>(</c-><c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-> <c- o>==</c-> <c- n>Q</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>));</c->

  <c- n>copy</c-><c- p>(</c-><c- n>A</c-><c- p>,</c-> <c- n>Q</c-><c- p>);</c->
  <c- k>const</c-> <c- b>int</c-> <c- n>info1</c-> <c- o>=</c-> <c- n>cholesky_tsqr_one_step</c-><c- p>(</c-><c- n>Q</c-><c- p>,</c-> <c- n>R</c-><c- p>);</c->
  <c- k>if</c-><c- p>(</c-><c- n>info1</c-> <c- o>!=</c-> <c- mi>0</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>info1</c-><c- p>;</c->
  <c- p>}</c->
  <c- c1>// Use one step of iterative refinement to improve accuracy.</c->
  <c- k>const</c-> <c- b>int</c-> <c- n>info2</c-> <c- o>=</c-> <c- n>cholesky_tsqr_one_step</c-><c- p>(</c-><c- n>Q</c-><c- p>,</c-> <c- n>R_tmp</c-><c- p>);</c->
  <c- k>if</c-><c- p>(</c-><c- n>info2</c-> <c- o>!=</c-> <c- mi>0</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>info2</c-><c- p>;</c->
  <c- p>}</c->
  <c- c1>// R = R_tmp * R</c->
  <c- n>using</c-> <c- n>std</c-><c- o>::</c-><c- n>linalg</c-><c- o>::</c-><c- n>triangular_matrix_left_product</c-><c- p>;</c->
  <c- n>triangular_matrix_left_product</c-><c- p>(</c-><c- n>R_tmp</c-><c- p>,</c-> <c- n>upper_triangle</c-><c- p>,</c->
                                 <c- n>explicit_diagonal</c-><c- p>,</c-> <c- n>R</c-><c- p>);</c->
  <c- k>return</c-> <c- mi>0</c-><c- p>;</c->
<c- p>}</c->
</pre>
  </main>
<script>
(function() {
  "use strict";
  var collapseSidebarText = '<span aria-hidden="true">←</span> '
                          + '<span>Collapse Sidebar</span>';
  var expandSidebarText   = '<span aria-hidden="true">→</span> '
                          + '<span>Pop Out Sidebar</span>';
  var tocJumpText         = '<span aria-hidden="true">↑</span> '
                          + '<span>Jump to Table of Contents</span>';

  var sidebarMedia = window.matchMedia('screen and (min-width: 78em)');
  var autoToggle   = function(e){ toggleSidebar(e.matches) };
  if(sidebarMedia.addListener) {
    sidebarMedia.addListener(autoToggle);
  }

  function toggleSidebar(on) {
    if (on == undefined) {
      on = !document.body.classList.contains('toc-sidebar');
    }

    /* Don’t scroll to compensate for the ToC if we’re above it already. */
    var headY = 0;
    var head = document.querySelector('.head');
    if (head) {
      // terrible approx of "top of ToC"
      headY += head.offsetTop + head.offsetHeight;
    }
    var skipScroll = window.scrollY < headY;

    var toggle = document.getElementById('toc-toggle');
    var tocNav = document.getElementById('toc');
    if (on) {
      var tocHeight = tocNav.offsetHeight;
      document.body.classList.add('toc-sidebar');
      document.body.classList.remove('toc-inline');
      toggle.innerHTML = collapseSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, 0 - tocHeight);
      }
      tocNav.focus();
      sidebarMedia.addListener(autoToggle); // auto-collapse when out of room
    }
    else {
      document.body.classList.add('toc-inline');
      document.body.classList.remove('toc-sidebar');
      toggle.innerHTML = expandSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, tocNav.offsetHeight);
      }
      if (toggle.matches(':hover')) {
        /* Unfocus button when not using keyboard navigation,
           because I don’t know where else to send the focus. */
        toggle.blur();
      }
    }
  }

  function createSidebarToggle() {
    /* Create the sidebar toggle in JS; it shouldn’t exist when JS is off. */
    var toggle = document.createElement('a');
      /* This should probably be a button, but appearance isn’t standards-track.*/
    toggle.id = 'toc-toggle';
    toggle.class = 'toc-toggle';
    toggle.href = '#toc';
    toggle.innerHTML = collapseSidebarText;

    sidebarMedia.addListener(autoToggle);
    var toggler = function(e) {
      e.preventDefault();
      sidebarMedia.removeListener(autoToggle); // persist explicit off states
      toggleSidebar();
      return false;
    }
    toggle.addEventListener('click', toggler, false);


    /* Get <nav id=toc-nav>, or make it if we don’t have one. */
    var tocNav = document.getElementById('toc-nav');
    if (!tocNav) {
      tocNav = document.createElement('p');
      tocNav.id = 'toc-nav';
      /* Prepend for better keyboard navigation */
      document.body.insertBefore(tocNav, document.body.firstChild);
    }
    /* While we’re at it, make sure we have a Jump to Toc link. */
    var tocJump = document.getElementById('toc-jump');
    if (!tocJump) {
      tocJump = document.createElement('a');
      tocJump.id = 'toc-jump';
      tocJump.href = '#toc';
      tocJump.innerHTML = tocJumpText;
      tocNav.appendChild(tocJump);
    }

    tocNav.appendChild(toggle);
  }

  var toc = document.getElementById('toc');
  if (toc) {
    createSidebarToggle();
    toggleSidebar(sidebarMedia.matches);

    /* If the sidebar has been manually opened and is currently overlaying the text
       (window too small for the MQ to add the margin to body),
       then auto-close the sidebar once you click on something in there. */
    toc.addEventListener('click', function(e) {
      if(e.target.tagName.toLowerCase() == "a" && document.body.classList.contains('toc-sidebar') && !sidebarMedia.matches) {
        toggleSidebar(false);
      }
    }, false);
  }
  else {
    console.warn("Can’t find Table of Contents. Please use <nav id='toc'> around the ToC.");
  }

  /* Wrap tables in case they overflow */
  var tables = document.querySelectorAll(':not(.overlarge) > table.data, :not(.overlarge) > table.index');
  var numTables = tables.length;
  for (var i = 0; i < numTables; i++) {
    var table = tables[i];
    var wrapper = document.createElement('div');
    wrapper.className = 'overlarge';
    table.parentNode.insertBefore(wrapper, table);
    wrapper.appendChild(table);
  }

})();
</script>