text:
# create_cat_design: Computerized Adaptive Test (CAT) Simulation Design In irt: Item Response Theory and Computerized Adaptive Testing Functions

 create_cat_design R Documentation

## Computerized Adaptive Test (CAT) Simulation Design

### Description

create_cat_design is a helper function for cat_sim and cat_sim_fast functions. It defines the simulation design.

Ideally, there is a design element for each item. So within this design (which is a list), there are $k$ design elements for each potentially administered item. Each of these sub-design elements are also a list.

### Usage

create_cat_design(
ip = NULL,
title = NULL,
true_ip = NULL,
first_item_rule = "fixed_theta",
first_item_par = list(theta = 0),
next_item_rule = "mfi",
next_item_par = NULL,
ability_est_rule = "eap",
ability_est_par = NULL,
final_ability_est_rule = NULL,
final_ability_est_par = NULL,
termination_rule = c("min_item", "min_se", "max_item"),
termination_par = list(min_item = 10, min_se = 0.33, max_item = 20),
testlet_rules = NULL,
exposure_control_rule = NULL,
exposure_control_par = NULL,
content_bal_rule = NULL,
content_bal_par = NULL,
ability_type = "theta"
)

### Arguments

 ip An Itempool-class object containing item parameters, content information, etc. If ip = NULL this means this is an infinite item pool, where b is on demand, c = 0 and a = 1, D = 1.7. If true_ip argument is NULL, this item pool will be used to generate item responses. title A string value representing the title of this CAT design. true_ip An Itempool-class object which holds the true values of item pool parameters that will be used to generate item responses. This is an optional argument. If it is NULL and ip is not missing, then, item responses will be generated using ip. Default: NULL first_item_rule The method how the first item is administered. The main effect of this is to select the first item administered to an examinee. If, for example, first item is desired to be a fixed one or randomly selected from the item pool, then set that rule in next_item_rule. Default: 'fixed_theta' Possible values and required parameters: NULLIf no separate first item selection rule is necessary, the first item will be selected using the next_item_rule and it's parameters next_item_par. "fixed_theta"Fixed starting value. Required parameters for first_item_par argument if this rule is selected: thetaThe value of the initial theta estimate. "theta_range"An initial theta estimate within min_theta and max_theta will be randomly selected. Required parameters for first_item_par argument if this rule is selected: min_thetaMinimum theta value of the interval. max_thetaMaximum theta value of the interval. first_item_par Parameters for the first item rule. Default: list(theta = 0) next_item_rule A vector of length one or length maximum test length which is designating the next item selection rules. Default: 'mfi' Note that, currently, if there are testlets in an item pool and a testlet is selected for administration using one of the methods below, all items within that testlet will be administered regardless of the next item selection rule. Possible values and required parameters: random Randomly select items from the item pool. Exposure control rules and parameters will be ignored for this selection rule. Required parameters: None. mfi Maximum Fisher Information. Required parameters: None. mepv Minimum Expected Posterior Variance. Required Parameters: "var_calc_method" Which method to use to calculate the posterior variance. See Equation (4) of Choi and Swartz (2009), Comparison of CAT Criteria for Polytomous Items. Available options are: "eap" Use the variance from expected a posteriori estimation. "owen" Use the variance from Owen's Bayesian estimation. For "Rasch", "1PL", "2PL", "3PL" models this is much faster than "eap" option above. b_optimal Select item which has item difficulty that is close to the current ability estimate. Required parameters: None. fixed Administer a fixed set of items from the item pool. This is basically a linear fixed length test where the order of items are predefined. Exposure control rules and parameters will be ignored for this selection rule. Required Parameters: item_id A vector of the item IDs that should be administered. next_item_par A list of length one or length maximum test length that sets the parameters of next item selection rules. It can also be NULL, in which case no parameters necessary for that next item selection procedure. Default: NULL ability_est_rule A vector of length one or length maximum test length which is designating the next item selection rules. Default: "eap" Possible values and required parameters: "eap" Expected-a-posteriori. Required parameters: prior_dist Distribution of the prior distribution. Available values: * norm for normal distribution, * unif for uniform distribution. The default value is norm. prior_par A vector of prior parameters. * For normal distribution c(0, 1), see ?dnorm * For uniform distribution c(-3, 3), see ?dunif The default value is c(0, 1). min_theta Minimum possible value of theta. It is a lower bound. The default value is -4. max_theta Maximum possible value of theta. It is an upper bound. The default value is 4. no_of_quadrature The number of quadrature, more specifically the number of bins the theta range should be divided. The more bins, the more precise (and slower) the estimates will be. The default value is 50. "map" Maximum-a-posteriori (Bayes Modal). Required parameters: prior_dist Distribution of the prior distribution. Currently only available value is: * norm for normal distribution, The default value is norm. prior_par A vector of prior parameters. * For normal distribution c(0, 1), see ?dnorm * For uniform distribution c(-3, 3), see ?dunif The default value is c(0, 1). min_theta Minimum possible value of theta. It is a lower bound. The default value is -4. max_theta Maximum possible value of theta. It is an upper bound. The default value is 4. tol The tolerance (precision) level of the estimate. The default value is 0.00001. "owen" Owen's Bayesian Estimation Required parameters: prior_meanPrior mean value. The default value is 0. prior_varPrior variance value.The default value is 1. "ml" Maximum likelihood estimation using Newton-Raphson algorithm. If this method is used, the standard error of ability estimates are calculated using the inverse information value at this theta estimate. Required parameters: min_thetaMinimum possible value of theta. It is a lower bound. The default value is -4. max_thetaMaximum possible value of theta. It is an upper bound. The default value is 4. criterionThis value determines the accuracy of estimates. Smaller values lead more accuracy but the speed of estimation reduces as the value of criterion decreases. The default value is 0.001. "eap_ml" Expected-a-posteriori until an imperfect item response string, then switch to Maximum Likelihood estimation. Required parameters: prior_dist Distribution of the prior distribution. Available values: norm for normal distribution, unif for uniform distribution. prior_par A vector of prior parameters. For normal distribution c(0, 1), see ?dnorm For uniform distribution c(-3, 3), see ?dunif min_theta Minimum possible value of theta. It is a lower bound. max_theta Maximum possible value of theta. It is an upper bound. no_of_quadrature The number of quadrature, more specifically the number of bins the theta range should be divided. The more bins, the more precise (and slower) the estimates will be. "map_ml" Maximum-a-posteriori until an imperfect item response string, then switch to Maximum Likelihood estimation. Required parameters: prior_dist Distribution of the prior distribution. Available values: norm for normal distribution, prior_par A vector of prior parameters. For normal distribution c(0, 1), see ?dnorm min_theta Minimum possible value of theta. It is a lower bound. max_theta Maximum possible value of theta. It is an upper bound. tol The tolerance (precision) level of the estimate. The default value is 0.00001. "sum_score" Simple sum score. Required parameters: NULL ability_est_par A list of length one or length maximum test length that sets the parameters of ability estimation rules. It can also be NULL. * If ability_est_rule = "eap" then the default is list(prior_dist = "norm", prior_par = list(mean = 0, sd = 2), min_theta = -4, max_theta = 4) * If ability_est_rule = "owen" then the default is list(prior_mean = 0, prior_var = 1) If it is NULL, either no parameters necessary for that ability estimation rule or the defaults of that ability selection rule will be selected. If it is a list of one, it means that the parameters will be the same throughout the test. The names of the list elements will represent the parameter types. A list of lists with length of maximum test length designate different parameters for different items in the test progress. final_ability_est_rule The ability estimation method that will be used to calculate the final ability estimate. The methods and the parameters are the same as ability_est_rule and ability_est_par. Please see those for details. Default: NULL final_ability_est_par A list of parameters that will be used for the method designated by the final_ability_est_rule. Default: NULL termination_rule This parameter determines how CAT algorithm decides terminate the test. The order of termination rules is important. The algorithm will check the rules in that order. If for example termination_rule = c('min_se', 'max_item'), first whether the SE smaller than a certain value checked and if it is smaller, then even the maximum number of items haven't been administered, test will terminate. The "min_item" and "max_item" has a special property where, for "min_item", if the number of items administered smaller than min_item, then test will not terminate regardless of whether other rules satisfied. Similarly, for "max_item", if the number of items is larger than max_item, the test will terminate regardless of whether other conditions satisfied or not. If both "min_item" and "max_item" are in termination rules, then, test will end when both conditions satisfied, i.e. when the number of items administered is equal to or larger than max_item value in termination_par. The "test length" refers to "Item" objects, i.e. individual items not testlets. For example, if an item pool has 10 testlets each having 2 items and 15 standalone items which are not within a testlet, then the test length can go up to 35 (2 x 10 + 15). Default: c("min_item", "min_se", "max_item") "termination_rule" should be a vector that composed of the following termination rules: "min_item"The minimum number of items should be satisfied. If the number of administered items are equal to or larger than this number test ends. "max_item"The maximum number of items should not be exceeded. . If this is missing, then the item pool size will be set as maximum length. "min_se"If the standard error exceeds min_se value, then the test will terminate. "sprt"Sequential Probability Ratio Test (SPRT). SPRT tests two hypotheses: H_0: Examinee's ability \hat θ = θ_0 H_1: Examinee's ability \hat θ = θ_1 After the administration of each item, the likelihood (or log-likelihood) of the response string is calculated at θ_0 and θ_1. The ratio of this likelihood is then compared to two decision points, A and B. LR = \frac{L(θ = theta_1)}{θ = theta_0} In order to calculate the lower (A) and upper (B) decision points, one needs to set α and β. α represents the rate of false positive classification errors (0 < α < 1), i.e. examinees whose true classification is fail but passed at the end of test. β is the rate of false negative classification errors (0 < β < 1), i.e. examinees whose true classification is pass but failed at the end of test. A and B can be calculated as: A = \frac{1 - β}{α} B = \frac{β}{1 - α} If LR > A, examinee passes the test and if LR < B examinee fails the test. If B < LR < A, test continues until the maximum number of items reached (or some other test termination criteria satisfied.) "sprt" termination rule needs termination_par, where the following parameters should be given in a list: "theta_0"The highest theta value that the test developer is willing to fail an examinee. "theta_1"The lowest theta value that the test developer is willing to pass an examinee. "alpha"The rate of false positive classification errors (0 < alpha < 1), i.e. examinees whose true classification is fail but passed at the end of test. "beta"The rate of false negative classification errors (0 < beta < 1), i.e. examinees whose true classification is pass but failed at the end of test. Example: termination_par = list(sprt = list(theta_0 = -.9, theta_1 = -.1, alpha = 0.05, beta = 0.05)) termination_par A list of termination rule parameters. This is a named list with length equal to the length of termination_rule argument. The names of the list elements should correspond to the elements of termination_rule argument. Default: list(min_item = 10, min_se = 0.33, max_item = 20) testlet_rules A list containing arguments that specify the rules that will be used within a testlet. The default value is NULL where the following rules will be applied if there is a testlet: list(next_item_rule = "none", termination_rule = "max_item", termination_par = list(max_item = 999)) where if a testlet is selected all items of this testlet is selected (unless the a testlet has more than 999 items.). Each item is selected with the order it appears in the testlet. It is assumed that items within testlet are administered together. In other words, an item that does not belong to a selected testlet cannot be administered between two items that belong to the same testlet. The following list elements are available: next_item_ruleThe way item selection is performed within a testlet. Following options are available: "none"Items are selected with the order of observed in the testlet. "mfi"Maximum Fisher Information. The most informative unadministered item within the testlet at the current ability estimate is selected. "termination_rule"The rule that should be satisfied to stop administering items from a testlet. Currently, only "max_item" is available. The test will terminate when maximum number of items is reached or there are no items left in the testlet. "termination_par"The test termination parameters. See the "termination_par" above in the main function for available options. exposure_control_rule A vector of length one or length maximum test length which is designating the next item selection rules. It can be NULL in which case there won't be any exposure control. Default: NULL, No exposure control will be imposed on item selection. Possible values and required parameters: NULLNo exposure control. "randomesque" Select one of the most informative num_items items. num_itemsThe number of items to select from. "sympson-hetter" The algorithm of Sympson-Hetter exposure control is explained in Sympson and Hetter (1985). This method does not require any additional "exposure_control_par" but each item/testlet should have a "misc" slot like the following misc = list(sympson_hetter_k = .75). When using 'sympson-hetter' exposure control rule, please ensure that there are sufficient number of items with 'sympson_hetter_k' values 1. Otherwise, examinees might not get a complete test and an error might be raised by the simulation function. exposure_control_par A list of length one or maximum test length designating the exposure control for each item. If there are no parameters it will be NULL. Default: NULL content_bal_rule Whether a content balancing is imposed on item selection. Default value is NULL, where no content balancing will be imposed on item selection. Default: NULL Possible values and required parameters: NULLNo content balancing. max_discrepancyGiven a target content distribution, the content with maximum discrepancy with target discrepancy will be administered. Required parameters: target_distTarget content ratios. For example, suppose there are three content areas: Geometry, Algebra and Arithmetic. If the plan for the test is to include 30 Arithmetic items, then, the target_dist should be: c(Geometry = .3, Arithmetic = .2, Algebra = .5). The names in the vector should correspond to the names of the content areas in the item pool. target_dist should include each content area within the item pool for it to work properly. If the sum of the target_dist is larger than 1, it will be converted to ratios. content_bal_par Parameters of content_bal_rule. A list, a list of lists or NULL. Default: NULL ability_type The type of ability the test is measuring. By default it is IRT based single 'theta'. "theta"Theta for unidimensional IRT models "multi_theta"Theta vector for multidimensional IRT models (Not Implemented Yet). "cdm"An attribute vector (Not Implemented Yet). "raw_score"Raw score (i.e. total score) of an examinee. Default: "theta"

### Value

A cat_design object that holds the test specifications of a CAT.

Emre Gonulates

### References

Sympson, J., & Hetter, R. D. (1985). Controlling item-exposure rates in computerized adaptive testing. 973–977.

cat_sim

### Examples

### Example Designs ###
# Fixed length test IRT test with ability estimation EAP-ML
n_items <- 30
ip <- itempool(data.frame(a = runif(n_items, .5, 1.5), b = rnorm(n_items)))
cd <- create_cat_design(ip = ip, next_item_rule = 'random',
termination_rule = 'min_item',
termination_par = list('min_item' = n_items))
cd
create_cat_design(ip = ip, next_item_rule = 'random')

n_ip <- 55
ip <- itempool(data.frame(a = runif(n_ip, .5, 1.5), b = rnorm(n_ip)))
# Check the default:
create_cat_design()
create_cat_design(ip = ip)

### Termination Rule ###
create_cat_design(
termination_rule = c('min_item', 'min_se', 'max_item'),
termination_par = list(min_item = 10, min_se = .33, max_item = 20))

cd <- create_cat_design(ip = ip, termination_rule = c('min_item', 'min_se'),
termination_par = list(min_item = 10, min_se = .33))

### Next Item Rule ###
create_cat_design(ip = ip, next_item_rule = 'random', next_item_par = NULL)
create_cat_design(
ip = ip, termination_rule = c('min_item', 'max_item'),
termination_par = list(min_item = 20, max_item = 20),
next_item_rule = 'fixed',
next_item_par = list(item_id = ip\$item_id[1:20]))

# Linear test where all of the items in the item pool administered in the
# same order as item pool
ip <- generate_ip(n = 15)
create_cat_design(
ip = ip, termination_rule = c('max_item'),
termination_par = list(max_item = 15),
next_item_rule = 'fixed')

# Generate an item pool with two testlets and three standalone items and
# administer first seven items as a linear test.
ip <- c(generate_testlet(n = 2, testlet_id = "t1"), generate_ip(n = 3),
generate_testlet(n = 5, testlet_id = "t2"))
create_cat_design(
ip = ip, termination_rule = c('max_item'),
termination_par = list(max_item = 7),
next_item_rule = 'fixed')

# A linear test where the item order is predefined.
ip1 <- itempool(data.frame(b = rnorm(5)), item_id = paste0("i",1:5))
cd <- create_cat_design(
ip = ip1,
next_item_rule = 'fixed',
next_item_par = list(item_id = c("i3", "i2", "i4", "i5", "i1")),
ability_est_rule = "eap",
termination_rule = 'max_item', termination_par = list(max_item = 5))

### Ability Estimation Rule ###
create_cat_design(
ability_est_rule = 'eap',
ability_est_par = list(prior_dist = 'unif',
prior_par = list(min = -2, max = 2),
min_theta = -4, max_theta = 4,
create_cat_design(
ability_est_rule = 'ml',
ability_est_par = list(min_theta = -4, max_theta = 4, criterion = 0.01))

### Exposure Control ###
create_cat_design(exposure_control_rule = 'randomesque',
exposure_control_par = list(num_items = 1))

# 5-4-3-2-1 exposure control
create_cat_design(
exposure_control_rule = 'randomesque',
exposure_control_par = lapply(c(5:1, rep(1, 15)),
function(x) list(num_items = x)))

### Content Balancing ###
create_cat_design(
content_bal_rule = 'max_discrepancy',
content_bal_par = list(target_dist = c(
Geometry = .3, Rational Numbers = .2, Algebra = .5)))

irt documentation built on Nov. 10, 2022, 5:50 p.m.


text:
jbritto Group Title What is the limit of (1+cosx)/sinx when x approaches 0 one year ago one year ago

• This Question is Open
1. zugzwang Group Title

l'Hôpital's rule, are you allowed to use that?

2. zugzwang Group Title

Wait, I panicked... no l'Hôpital's rule, I'm sorry

3. myininaya Group Title

How can you use l-hospital here?

4. myininaya Group Title

You have 2/0 not 0/0

5. myininaya Group Title

$\lim_{x \rightarrow 0}\frac{1+\cos(x)}{\sin(x)}$ Recall the following: $\lim_{x \rightarrow 0}\frac{\sin(x)}{x}=1 \text{ , } \lim_{x \rightarrow 0}\frac{\cos(x)-1}{x}=0$ Let's see if we can use that here: $\lim_{x \rightarrow 0}\frac{\cos(x)+1}{\sin(x)} \cdot \frac{\cos(x)-1}{\cos(x)-1}$ $\lim_{x \rightarrow 0} \frac{\cos^2(x)-1}{\sin(x)(\cos(x)-1)}$ $\lim_{x \rightarrow 0}=\frac{-\sin^2(x)}{\sin(x)(\cos(x)-1)}$ $\lim_{x \rightarrow 0}\frac{-\sin(x)}{\cos(x)-1}$ Now try it :)

6. myininaya Group Title

Using L'hospital you will get something easier to look at :)

7. myininaya Group Title

We didn't actually need any of those things I told you to recall above :)

8. jbritto Group Title

Thanks. It still becomes -1/0 which is undefined ??

9. shubhamsrg Group Title

its not -1/0 but its 0/0 @jbritto sin0 = 0 cos0 =1

10. shubhamsrg Group Title

anyways,,there is an alternative also.. 1+ cosx = 1 + 2 cos^2 (x/2) -1 = 2cos^2 (x/2) and sinx = 2 sin(x/2) cos(x/2) so whole expression is 2 cos^2(x/2) / 2 sin(x/2) cos(x/2) = cos(x/2)/ sin(x/2) = cot (x/2) not plug in x=0

11. shubhamsrg Group Title

oh,,so you were saying it becomes 1/0 !! ohh,,am sorry.. in that case either the limit is undefined or you maybe made a typing error//

12. jbritto Group Title

yes. applying L-Hosp rule, it will become -cosx/sinx which is -1/0 undefined

format: plain


text:
# 5. Quantum Circuit Simulation¶

quimb has powerful support for simulating quantum circuits via its ability to represent and contract arbitrary geometry tensor networks. However, because its representation is generally neither the full wavefunction (like many other simulators) or a specific TN (for example an MPS or PEPS like some other simulators), using it is a bit different and requires potentially extra thought.

Specifically, the computational memory and effort is very sensitive to what you want to compute, but also how long you are willing to spend computing how to compute it - essentially, pre-processing.

Note

All of which to say, you are unfortunately quite unlikely to achieve the best performance without some tweaking of the default arguments.

Nonetheless, here’s a quick preview of the kind of circuit that many classical simulators might struggle with - an 80 qubit GHZ-state prepared using a completely randomly ordered sequence of CNOTs:

[1]:

%config InlineBackend.figure_formats = ['svg']

import random
import quimb as qu
import quimb.tensor as qtn

N = 80
circ = qtn.Circuit(N)

# randomly permute the order of qubits
regs = list(range(N))
random.shuffle(regs)

# hamadard on one of the qubits
circ.apply_gate('H', regs[0])

# chain of cnots to generate GHZ-state
for i in range(N - 1):
circ.apply_gate('CNOT', regs[i], regs[i + 1])

# sample it once
for b in circ.sample(1):
print(b)

11111111111111111111111111111111111111111111111111111111111111111111111111111111

As mentioned above, various pre-processing steps need to occur (which will happen on the first run if not explicitly called). The results of these are cached such that the more you sample the more the simulation should speed up:

[2]:

%%time
# sample it 8 times
for b in circ.sample(8):
print(b)

00000000000000000000000000000000000000000000000000000000000000000000000000000000
11111111111111111111111111111111111111111111111111111111111111111111111111111111
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
11111111111111111111111111111111111111111111111111111111111111111111111111111111
00000000000000000000000000000000000000000000000000000000000000000000000000000000
11111111111111111111111111111111111111111111111111111111111111111111111111111111
00000000000000000000000000000000000000000000000000000000000000000000000000000000
CPU times: user 321 ms, sys: 301 µs, total: 321 ms
Wall time: 308 ms

Collect some statistics:

[3]:

%%time
from collections import Counter

# sample it 100 times, count results:
Counter(circ.sample(100))

CPU times: user 211 ms, sys: 24.3 ms, total: 235 ms
Wall time: 219 ms

[3]:

Counter({'11111111111111111111111111111111111111111111111111111111111111111111111111111111': 60,
'00000000000000000000000000000000000000000000000000000000000000000000000000000000': 40})

## 5.1. Simulation Steps¶

Here’s an overview of the general steps for a tensor network quantum circuit simulation:

1. Build the tensor network representation of the circuit, this involves taking the initial state (by default the product state $| 000 \ldots 00 \rangle$ ) and adding tensors representing the gates to it, possibly performing low-rank decompositions on them if beneficial.

2. Form the entire tensor network of the quantity you actually want to compute, this might include:

• the full, dense, wavefunction (i.e. a single tensor)

• a local expectation value or reduced density matrix

• a marginal probability distribution to sample bitstrings from, mimicking a real quantum computer (this is what is happening above)

• the fidelity with a target state or unitary, maybe to use automatic differentation to train the parameters of a given circuit to perform a specific task

3. Perform local simplifications on the tensor network to make it easier (possibly trivial!) to contract. This step, whilst efficient in the complexity sense, can still introduce some significant overhead.

4. Find a contraction path for this simplified tensor network. This a series of pairwise tensor contractions that turn the tensor network into a single tensor - represented by a binary contraction tree. The memory required for the intermediate tensors can be checked in advance at this stage.

5. Optionally slice (or ‘chunk’) the contraction, breaking it into many independent, smaller contractions, either to fit memory constraints or introduce embarassing parallelism.

6. Perform the contraction! Up until this point the tensors are generally very small and so can be easily passed to some other library with which to perform the actual contraction (for example, one with GPU support).

Warning

The overall computational effort memory required in this last step is very sensitive (we are talking possibly orders and order of magnitude) to how well one finds the so-called ‘contraction path’ or ‘contraction tree’ - which itself can take some effort. The overall simulation is thus a careful balancing of time spent (a) simplifying (b) path finding, and (c) contracting.

Note

It’s also important to note that this last step is where the exponential slow-down expected for generic quantum circuits will appear. Unless the circuit is trivial in some way, the tensor network simplification and path finding can only ever shave off a (potentially very significant) prefactor from an underlying exponential scaling.

## 5.2. Building the Circuit¶

The main relevant object is Circuit. Under the hood this uses gate_TN_1D(), which applies an operator on some number of sites to any notionally 1D tensor network (not just an MPS), whilst maintaining the outer indices (e.g. 'k0', 'k1', 'k2', ...). . The various options for applying the operator and propagating tags to it (if not contracted in) can be found in gate_TN_1D(). Note that the ‘1D’ nature of the TN is just for indexing, gates can be applied to arbitrary combinations of sites within this ‘register’.

The following is a basic example of building a quantum circuit TN by applying a variety of gates to, for visualization purposes, nearest neighbors in a chain.

[4]:

# 10 qubits and tag the initial wavefunction tensors
circ = qtn.Circuit(N=10)

for i in range(10):
circ.apply_gate('H', i, gate_round=0)

# 8 rounds of entangling gates
for r in range(1, 9):

# even pairs
for i in range(0, 10, 2):
circ.apply_gate('CNOT', i, i + 1, gate_round=r)

# Y-rotations
for i in range(10):
circ.apply_gate('RZ', 1.234, i, gate_round=r)

# odd pairs
for i in range(1, 9, 2):
circ.apply_gate('CZ', i, i + 1, gate_round=r)

# X-rotations
for i in range(10):
circ.apply_gate('RX', 1.234, i, gate_round=r)

for i in range(10):
circ.apply_gate('H', i, gate_round=r + 1)

circ

[4]:

<Circuit(n=10, num_gates=252, gate_opts={'contract': 'auto-split-gate', 'propagate_tags': 'register'})>

The basic tensor network representing the state is stored in the .psi attribute, which we can then visualize:

[5]:

circ.psi.draw(color=['PSI0', 'H', 'CNOT', 'RZ', 'RX', 'CZ'])

Note by default the CNOT and CZ gates have been split via a rank-2 spatial decomposition into two parts acting on each site seperately but connected by a new bond. We can also graph the default (propagate_tags='register') method for adding site tags to the applied operators:

[6]:

circ.psi.draw(color=[f'I{i}' for i in range(10)])

Or since we supplied gate_round as an keyword (which is optional), the tensors are also tagged in that way:

[7]:

circ.psi.draw(color=['PSI0'] + [f'ROUND_{i}' for i in range(10)])

[8]:

# select the subnetwork of tensors with *all* following tags
circ.psi.select(['CNOT', 'I3', 'ROUND_3'], which='all')

[8]:

<TensorNetwork(tensors=1, indices=3)>

Note

The tensor(s) of each gate is/are also individually tagged like [f'GATE_{g}' for g in range(circ.num_gates)].

The full list of currently implemented gates is here:

[9]:

"  ".join(qtn.circuit.GATE_FUNCTIONS)

[9]:

'H  X  Y  Z  S  T  X_1_2  Y_1_2  Z_1_2  W_1_2  HZ_1_2  CNOT  CX  CY  CZ  IS  ISWAP  IDEN  SWAP  RX  RY  RZ  U3  U2  U1  CU3  CU2  CU1  FS  FSIM  RZZ'

### 5.2.1. Parametrized Gates¶

Of these gates, any which take parameters - ['RZ', 'RY', 'RZ', 'U3', 'FSIM', 'RZZ'] - can be ‘parametrized’, which adds the gate to the network as a PTensor. The main use of this is that when optimizing a TN, for example, the parameters that generate the tensor data will be optimized rather than the tensor data itself.

[10]:

circ_param = qtn.Circuit(6)

for l in range(3):
for i in range(0, 6, 2):
circ_param.apply_gate('FSIM', random.random(), random.random(), i, i + 1, parametrize=True, contract=False)
for i in range(1, 5, 2):
circ_param.apply_gate('FSIM', random.random(), random.random(), i, i + 1, parametrize=True, contract=False)
for i in range(6):
circ_param.apply_gate('U3', random.random(), random.random(), random.random(), i, parametrize=True)

circ_param.psi.draw(color=['PSI0', 'FSIM', 'U3'])

We’ve used the contract=False option which doesn’t try and split the gate tensor in any way, so here there is now a single tensor per two qubit gate. In fact, for 'FSIM' and random parameters there is no low-rank decomposition that would happen anyway, but this is also the only mode compatible with parametrized tensors:

[11]:

circ_param.psi['GATE_0']

[11]:

PTensor(shape=(2, 2, 2, 2), inds=('_df874bAARUu', '_df874bAARUo', '_df874bAARUf', '_df874bAARUg'), tags=oset(['FSIM', 'GATE_0', 'I0', 'I1']))

For most tasks like contraction these are transparently handled like normal tensors:

[12]:

circ_param.amplitude('101001')

[12]:

(-0.028363740312282972+0.08561344641421921j)

## 5.3. Forming the Target Tensor Network¶

You can access the wavefunction tensor network $$U |0\rangle^{\otimes{N}}$$ or more generally $$U |\psi_0\rangle$$ with Circuit.psi or just the unitary, $$U$$, with Circuit.uni, and then manipulate and contract these yourself. However, there are built-in methods for constructing and contracting the tensor network to perform various common tasks.

### 5.3.1. Compute an amplitude¶

This computes a single wavefunction amplitude coefficient, or transition amplitude:

$c_x = \langle x | U | \psi_0 \rangle$

with, $$x=0101010101 \ldots$$, for example. The probability of sampling $$x$$ from this circuit is $$|c_x|^2$$.

Example usage:

[13]:

circ.amplitude('0101010101')

[13]:

(-0.006267589645294041+0.012702244544177423j)

### 5.3.2. Compute a local expectation¶

For an operator $$G_{\bar{q}}$$ acting on qubits $$\bar{q}$$, this computes:

$\langle \psi_{\bar{q}} | G_{\bar{q}} | \psi_{\bar{q}} \rangle$

where $$\psi_{\bar{q}}$$ is the circuit wavefunction but only with gates which are in the ‘reverse lightcone’ (i.e. the causal cone) of qubits $$\bar{q}$$. In the picture above the gates which we know cancel to the identity have been greyed out (and removed from the TN used).

Example usage:

[14]:

circ.local_expectation(qu.pauli('Z') & qu.pauli('Z'), (4, 5))

[14]:

(-0.01818896518545625+1.962405932198763e-17j)

You can compute several individual expectations on the same sites by supplying a list (they are computed in a single contraction):

[15]:

circ.local_expectation(
[qu.pauli('X') & qu.pauli('X'),
qu.pauli('Y') & qu.pauli('Y'),
qu.pauli('Z') & qu.pauli('Z')],
where=(4, 5),
)

[15]:

((-0.0057847192590974456+6.1257422745431e-17j),
(0.05890188167924257+3.0357660829594124e-17j),
(-0.018188965185456245+5.410168840702667e-17j))

### 5.3.3. Compute a reduced density matrix¶

This similarly takes a subset of the qubits, $$\bar{q}$$, and contracts the wavefunction with its bra, but now only the qubits outside of $$\bar{q}$$, producing a reduced density matrix:

$\rho_{\bar{q}} = \mathrm{Tr}_{\bar{p}} | \psi_{\bar{q}} \rangle \langle \psi_{\bar{q}} |$

where the partial trace is over $$\bar{p}$$, the complementary set of qubits to $$\bar{q}$$. Obviously once you have $$\rho_{\bar{q}}$$ you can compute many different local expecatations and so it can be more efficient than repeatedly calling local_expectation().

Example usage:

[16]:

circ.partial_trace((4, 5)).round(3)

[16]:

array([[ 0.252+0.j   ,  0.013+0.011j, -0.019+0.007j, -0.016-0.003j],
[ 0.013-0.011j,  0.255-0.j   ,  0.013+0.014j,  0.02 +0.017j],
[-0.019-0.007j,  0.013-0.014j,  0.254+0.j   ,  0.019+0.012j],
[-0.016+0.003j,  0.02 -0.017j,  0.019-0.012j,  0.239-0.j   ]])

### 5.3.4. Compute a marginal probability distribution¶

This method computes the probability distribution over some qubits, $$\bar{q}$$, conditioned on some partial fixed result on qubits $$\bar{f}$$ (which can be no qubits).

$p(\bar{q} | x_{\bar{f}}) = \mathrm{diag} \mathrm{Tr}_{\bar{p}} \langle x_{\bar{f}} | \psi_{\bar{f} \cup \bar{q}} \rangle \langle \psi_{\bar{f} \cup \bar{q}} | x_{\bar{f}} \rangle$

Here only the causal cone relevant to $$\bar{f} \cup \bar{q}$$ is needed, with the remaining qubits, $$\bar{p}$$ being traced out. We directly take the diagonal within the contraction using hyper-indices (depicted as a COPY-tenso above) to avoid forming the full reduced density matrix. The result is a $$2^{|\bar{q}|}$$ dimensional tensor containing the probabilites for each bit-string $$x_{\bar{q}}$$, given that we have already ‘measured’ $$x_{\bar{f}}$$.

Example usage:

[17]:

p = circ.compute_marginal((1, 2), fix={0: '1', 3: '0', 4: '1'}, dtype='complex128')
p

[17]:

array([[0.03422455, 0.02085596],
[0.03080204, 0.02780321]])

[18]:

qtn.circuit.sample_bitstring_from_prob_ndarray(p / p.sum())

[18]:

'00'

### 5.3.5. Generate unbiased samples¶

The main use of compute_marginal() is as a subroutine used to generate unbiased samples from circuits. We first pick some group of qubits, $$\bar{q_A}$$ to ‘measure’, then condition on the resulting bitstring $$x_{\bar{q_A}}$$, to compute the marginal on the next group of qubits $$\bar{q_B}$$ and so forth. Eventually we reach the ‘final marginal’ where we no longer need to trace any qubits out, so instead we can compute:

$p(\bar{q_Z} | x_{\bar{q_A}} x_{\bar{q_B}} \ldots) = |\langle x_{\bar{q_A}} x_{\bar{q_B}} \ldots | \psi \rangle|^2$

since the ‘bra’ representing the partial bit-string only acts on some of the qubits this object is still a $$2^{|\bar{q}|}$$ dimensional tensor, which we sample from to get the final bit-string $$x_{\bar{q_z}}$$. The overall sample generated is then the concatenation of all these bit-strings:

$x_{\bar{q_A}} x_{\bar{q_B}} \ldots x_{\bar{q_Z}}$

As such, to generate a sample once we have put our qubits into $$N_g$$ groups, we need to perform $$N_g$$ contractions. The contractions near the beginning are generally easier since we only need the causal cone for a small number of qubits, and the contractions towards the end are easier since we have largely or fully severed the bonds between the ket and bra by conditioning.

This is generally more expensive than computing local quantities but there are a couple of reprieves:

1. Because of causality we are free to choose the order and groupings of the qubits in whichever way is most efficient.

The automatic choice is to start at the qubit(s) with the smallest reverse lightcone and greedily expand (see section below). Grouping the qubits together can have a large beneficial impact on overall computation time, but imposes a hard upper limit on the required memory like $$2^{|\bar{q}|}$$.

Note

You can set the group size to be that of the whole sytem, which is equivalent to sampling from the full wavefunction, if you want to do this, it would be more efficient to call simulate_counts(), which doesn’t draw the samples individually.

1. Once we have computed a particular marginal we can can cache the result, meaning if we come across the same sub-string result, we don’t need to contract anything again, the trivial example being the first marginal we compute.

The second point is easy to understand if we think of the sampling process as the repeated exploration of a probability tree as above - which is shown for 3 qubits grouped individually, with a first sample of $$011$$ drawn. If the next sample we drew was $$010$$ we wouldn’t have to perform any more contractions, since we’d be following already explored branches. In the extreme case of the GHZ-state at the top, there are only two branches, so once we have generated the all-zeros and the all-ones result there we won’t need to perform any more contractions.

Example usage:

[19]:

for b in circ.sample(10, group_size=3):
print(b)

1000011000
0110000101
0111111010
1011001011
1111100100
1000100001
0110000111
0101011010
1100000000
0000111011

### 5.3.6. Generate samples from a chaotic circuit¶

Some circuits can be assumed to produce chaotic results, and a useful property of these is that if you remove (partially trace) a certain number of qubits, the remaining marginal probability distribution is close to uniform. This is like saying as we travel along the probability tree depicted above, the probabilities are all very similar until we reach ‘the last few qubits’, whose marginal distribution then depends sensitively on the bit-string generated so far.

If we know roughly what number of qubits suffices for this property to hold, $$m$$, we can uniformly sample bit-strings for the first $$f = N - m$$ qubits then we only need to contract the ‘final marginal’ from above. In other words, we only need to compute and sample from:

$p( \bar{m} | x_{\bar{f}} ) = |\langle x_{\bar{f}} | \psi \rangle|^2$

Where $$\bar{m}$$ is the set of marginal qubits, and $$\bar{f}$$ is the set of qubits fixed to a random bit-string. If $$m$$ is not too large, this is generally a very similar cost to that of computing a single amplitude.

Note

This task is the relevant method for classically simulating the results in “Quantum supremacy using a programmable superconducting processor”.

Example usage:

[20]:

for b in circ.sample_chaotic(10, marginal_qubits=5):
print(b)

0011100100
1101111111
0101010100
0011011111
0010101111
0000000001
1101101001
1101100111
0110111000
1101000100

Five of these qubits will now be sampled completely randomly.

### 5.3.7. Compute the dense vector representation of the state¶

In other words just contract the core circ.psi object into a single tensor:

$U | \psi_0 \rangle \rightarrow |\psi_{\mathrm{dense}}\rangle$

Where $$|\psi_{\mathrm{dense}}\rangle$$ is a column vector. Unlike other simulators however, the contraction order here isn’t defined by the order the gates were applied in, meaning the full wavefunction does not neccessarily need to be formed until the last few contractions.

Hint

For small to medium circuits, the benefits of doing this as compared with standard, ‘Schrodinger-style’ simulation might be negligible (since the overall scaling is still limited by the number of qubits). Indeed the savings are likely outweighed by the pre-processing step’s overhead if you are only running the circuit geometry once.

Example usage:

[21]:

circ.to_dense()

[21]:

[[ 0.022278+0.044826j]
[ 0.047567+0.001852j]
[-0.028239+0.01407j ]
...
[ 0.016   -0.008447j]
[-0.025437-0.015225j]
[-0.033285-0.030653j]]

### 5.3.8. Rehearsals¶

Each of the above methods can perform a trial run, where the tensor networks and contraction paths are generated and intermediates possibly cached, but the main contraction is not performed. Either supply rehearse=True or use the corresponding partial methods:

These each return a dict with the tensor network that would be contracted in the main part of the computation (with the key 'tn'), and the opt_einsum.PathInfo object describing the contraction path found for that tensor network (with the key 'info'). For example:

[22]:

rehs = circ.amplitude_rehearse()

# contraction width
W = qu.log2(rehs['info'].largest_intermediate)
W

[22]:

8.0

Upper twenties is the limit for standard (~10GB) amounts of RAM.

[23]:

# contraction cost
# N.B.  raw .opt_cost assumes *real* dtype FLOPs
#       * 4  to get complex dtype FLOPs (relevant for most QC)
#       / 2  to get dtype independent scalar OPs (the 'cost')
C = qu.log10(rehs['info'].opt_cost / 2)
C

[23]:

3.9607560909017727

[24]:

# perform contraction
rehs['tn'].contract(all, optimize=rehs['info'].path, output_inds=())

[24]:

(0.014567936533910614+0.039229453534987115j)

sample_rehearse() and sample_chaotic_rehearse() both return a dict of dicts, where the keys of the top dict are the (ordered) groups of marginal qubits used, and the values are the rehearsal dicts as above.

[25]:

rehs = circ.sample_rehearse(group_size=3)
rehs.keys()

[25]:

dict_keys([(0, 1, 2), (3, 4, 9), (5, 6, 7), (8,)])

[26]:

rehs[(3, 4, 9)].keys()

[26]:

dict_keys(['tn', 'info'])

### 5.3.9. Unitary Reverse Lightcone Cancellation¶

In several of the examples above we made use of ‘reverse lightcone’, or the set of gates that have a causal effect on a particular set of output qubits, $$\bar{q}$$, to work with a potentially much smaller TN representation of the wavefunction:

$| \psi_{\bar{q}} \rangle$

This can simply be understood as cancellation of the gate unitaries at the boundary where the bra and ket meet:

$U^{\dagger} U = \mathcal{1}$

if there are no operators or projectors breaking this bond between the bra and ket. Whilst such simplifications can be found by the local simplifications (see below) its easier and quicker to drop these explicitly.

You can see which gate tags are in the reverse lightcone of which regions of qubits by calling:

[27]:

# just show the first 10...
lc_tags = circ.get_reverse_lightcone_tags(where=(0,))
lc_tags[:10]

[27]:

('PSI0',
'GATE_0',
'GATE_1',
'GATE_2',
'GATE_3',
'GATE_4',
'GATE_5',
'GATE_6',
'GATE_7',
'GATE_8')

[28]:

circ.psi.draw(color=lc_tags, legend=False)

We can plot the effect this has as selecting only these, $$| \psi \rangle \rightarrow | \psi_{\bar{q}} \rangle$$, on the norm with the following:

[29]:

# get the reverse lightcone wavefunction of qubit 0
psi_q0 = circ.get_psi_reverse_lightcone(where=(0,))

# plot its norm
(psi_q0.H & psi_q0).draw(color=['PSI0'] + [f'ROUND_{i}' for i in range(10)])

Note

Although we have specified gate rounds here, this is not required to find the reverse lightcones, and indeed arbitrary geometry is handled too.

## 5.4. Locally Simplifying the Tensor Network (the simplify_sequence kwarg)¶

All of the main circuit methods take a simplify_sequence kwarg that controls local tensor network simplifications that are performed on the target TN object before the main contraction. The kwarg is a string of letters which is cycled through til convergence, which each letter corresponding to a different method:

The final object thus both depends on which letters and the order specified – 'ADCRS' is the default.

As an example, here is the amplitude tensor network of the circuit above, with only ‘rank simplification’ (contracting neighboring tensors that won’t increase rank) performed:

[30]:

(
circ
# get the tensor network
.amplitude_rehearse(simplify_sequence='R')['tn']
# plot it with each qubit register highlighted
.draw(color=[f'I{q}' for q in range(10)])
)

You can see that only 3+ dimensional tensors remain. Now if we turn on all the simplification methods we get an even smaller tensor network:

[31]:

(
circ
# get the tensor network
# plot it with each qubit register highlighted
.draw(color=[f'I{q}' for q in range(10)])
)

And we also now have hyper-indices - indices shared by more than two tensors - that have been introduced by the diagonal_reduce() method.

Hint

Of the five methods, only rank_simplify() doesn’t require looking inside the tensors at the sparsity structure. This means that, at least for the moment, it is the only method that can be back-propagated through, for example.

The five methods combined can have a significant effect on the complexity of the main TN to be contracted, in the most extreme case they can reduce a TN to a scalar:

[32]:

norm = circ.psi.H & circ.psi
norm

[32]:

<TensorNetwork1D(tensors=668, indices=802, L=10, max_bond=2)>

[33]:

norm.full_simplify_(seq='ADCRS')

[33]:

<TensorNetwork1D(tensors=1, indices=0, L=10, max_bond=1)>

Here, full_simplify(), (which is the method that cycles through the other five) has reduced the 500 tensors to a single scalar via local simplifications only. Clearly we know the answer should be 1 anyway, but its nice to confirm it can indeed be found automatically as well:

[34]:

norm ^ all

[34]:

0.9999999999999563

## 5.5. Finding a Contraction Path (the optimize kwarg)¶

As mentioned previously, the main computational bottleneck (i.e. as we scale up circuits, the step that always becomes most expensive) is the actual contraction of the main tensor network objects, post simplification. The cost of this step (which is recorded in the rehearsal’s 'info' objects) can be incredibly sensitive to the contraction path - the series of pairwise merges that define how to turn the collection of tensors into a single tensor.

You control this aspect of the quantum circuit simulation via the optimize kwarg, which can take a number different types of values:

1. A string, specifiying an opt_einsum registered path optimizer.

2. A custom opt_einsum.PathOptimizer instance, like those found in cotengra.

3. An explicit path - a sequence of pairs of ints - likely found from a previous rehearsal, for example.

Note

The default value is 'auto-hq' which is the highest quality preset opt_einsum has, but this is pretty unlikely to offer the best performance for large or complex circuits.

As an example we’ll show how to use each type of optimize kwarg for computing the local expecation:

$\langle \psi_{3, 4} | Z_3 \otimes Z_4 | \psi_{3, 4} \rangle$
[35]:

# compute the ZZ correlation on qubits 3 & 4
ZZ = qu.pauli('Z') & qu.pauli('Z')
where = (3, 4)

### 5.5.1. An opt_einsum preset¶

Frist we use the fast but low quality 'greedy' preset:

[36]:

rehs = circ.local_expectation_rehearse(ZZ, where, optimize='greedy')
tn, info = rehs['tn'], rehs['info']
info.opt_cost

[36]:

Decimal('255872')

Because we used a preset, the path is cached by quimb, meaning the path optimization won’t run again for the same geometry.

Hint

You can set a persistent disk cache for quimb to use with set_contract_path_cache().

Now we can run the actual computation, reusing that path automatically:

[37]:

%%timeit
circ.local_expectation(ZZ, where, optimize='greedy')

34.8 ms ± 361 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

We can compare this to just performing the main contraction:

[38]:

%%timeit
tn.contract(all, optimize=info.path, output_inds=())

4.19 ms ± 38.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Where we see that most of the time is evidently spent preparing the TN.

### 5.5.2. An opt_einsum.PathOptimizer instance¶

You can also supply a customized PathOptimizer instance here, an example of which is the opt_einsum.RandomGreedy optimizer (which is itself called by 'auto-hq' in fact).

[39]:

import opt_einsum as oe

# up the number of repeats and make it run in parallel
opt_rg = oe.RandomGreedy(max_repeats=256, parallel=True)

rehs = circ.local_expectation_rehearse(ZZ, where, optimize=opt_rg)
tn, info = rehs['tn'], rehs['info']
info.opt_cost

[39]:

Decimal('191560')

We see it has found a much better path than 'greedy', which is not so surprising.

Unlike before, if we want to reuse the path found from this, we can directly access the .path attribute from the info object (or the PathOptimizer object):

[40]:

%%timeit
circ.local_expectation(ZZ, where, optimize=info.path)

36.2 ms ± 1.44 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

We’ve shaved some time off but not much because the computation is not dominated by the contraction at this scale.

Note

If you supplied the opt_rg optimizer again, it would run for an additional 256 repeats, before returning its best path – this can be useful if you want to incrementally optimize the path, check its cost and then optimize more, before switching to .path when you actually want to contract, for example.

### 5.5.3. A custom opt_einsum.PathOptimizer instance¶

opt_einsum defines an interface for custom path optimizers, which other libraries, or any user, can subclass and then supply as the optimize kwarg and will thus be compatible with quimb. The cotengra library offers ‘hyper’-optimized contraction paths that are aimed at (and strongly recommended for) large and complex tensor networks. It provides:

• The optimize='hyper' preset (once cotengra is imported)

• The cotengra.HyperOptimizer single-shot path optimizer, (like RandomGreedy above)

• The cotengra.ReusableHyperOptimizer, which can be used for many contractions, and caches the results (optionally to disk)

The last is probably the most practical so we’ll demonstrate it here:

[41]:

import cotengra as ctg

# the kwargs ReusableHyperOptimizer take are the same as HyperOptimizer
opt = ctg.ReusableHyperOptimizer(
max_repeats=16,
reconf_opts={},
parallel=False,
progbar=True,
#     directory='ctg_path_cache',  # if you want a persistent path cache
)

rehs = circ.local_expectation_rehearse(ZZ, where, optimize=opt)
tn, info = rehs['tn'], rehs['info']
info.opt_cost

log2[SIZE]: 10.00 log10[FLOPs]: 4.91: 100%|██████████| 16/16 [00:12<00:00,  1.27it/s]

[41]:

Decimal('80384')

We can see even for this small contraction it has improved on the RandomGreedy path cost. We could use info.path here but since we have a ReusableHyperOptimizer path optimizer, this second time its called on the same contraction it will simply get the path from its cache anway:

[42]:

%%timeit
circ.local_expectation(ZZ, where, optimize=opt)

32.9 ms ± 441 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

Again, since the main contraction is very small, we don’t see any real improvement.

cotengra also has a ContractionTree object for manipulating and visualizing the contraction paths found.

[43]:

tree = ctg.ContractionTree.from_info(info)
tree.plot_tent()

Here the, grey network at the bottom is the TN to be contracted, and the tree above it depicts the series of pairwise contractions and their individual cost needed to find the output answer (the node at the top).

## 5.6. Performing the Contraction (the backend kwarg)¶

quimb and opt_einsum both try and be agnostic to the actual arrays they manipulate / contract. Currently however, the tensor network Circuit constructs and simplifies is made up of numpy.ndarray backed tensors since they are all generally very small:

[44]:

{t.size for t in tn}

[44]:

{4, 8}

When it comes to the actual contraction however, where large tensors will appear, it can be advantageous to use a different library to perform the contractions. If you specify a backend kwarg, before contraction, the arrays will converted to the backend, then the contraction performed, and the result converted back to numpy. The list of available backends is here, including:

• cupy

• jax (note this actively defaults to single precision)

• torch

• tensorflow

Sampling is an excellent candidate for GPU acceleration as the same geometry TNs are contracted over and over again and since sampling is inherently a low precision task, single precision arrays are a natural fit.

[45]:

for b in circ.sample(10, backend='jax', dtype='complex64'):
print(b)

0110110111
0111001011
0010010100
0010100111
0110000101
1100101001
1010100110
0110010010
1100000110
1110110111

Note

Both sampling methods, sample() and sample_chaotic(), default to dtype='complex64'. The other methods default to dtype='complex128'.

## 5.7. Performance Checklist¶

Here’s a list of things to check if you want to ensure you are getting the most performance out of your circuit simulation:

• What contraction path optimizer are you using? If performance isn’t great, have you tried cotengra?

• How are you applying the gates? For example, gate_opts={'contract': False} (no decomposition) can be better for diagonal 2-qubit gates.

• How are you grouping the qubits? For sampling, there is a sweet spot for group_size usually. For chaotic sampling, you might try the last $M$ marginal qubits rather than the first, for example.

• What local simplifications are you using, and in what order? simplify_sequence='SADCR' is also good sometimes.

• If the computation is contraction dominated, can you run it on a GPU?


text:
$$\require{cancel}$$

9.3: Block Spin Transformation

$$\newcommand\bes{\begin{split}}$$
$$\newcommand\ltwid{\propto}$$
$$\newcommand\ees{\end{split}}$$
$$\newcommand\mib{\mathbf}$$
$$\newcommand\Sa{\textsf a}$$
$$\newcommand\Sb{\textsf b}$$
$$\newcommand\Sc{\textsf c}$$
$$\newcommand\Sd{\textsf d}$$
$$\newcommand\Se{\textsf e}$$
$$\newcommand\Sf{\textsf f}$$
$$\newcommand\Sg{\textsf g}$$
$$\newcommand\Sh{\textsf h}$$
$$\newcommand\Si{\textsf i}$$
$$\newcommand\Sj{\textsf j}$$
$$\newcommand\Sk{\textsf k}$$
$$\newcommand\Sl{\textsf l}$$
$$\newcommand\Sm{\textsf m}$$
$$\newcommand\Sn{\textsf n}$$
$$\newcommand\So{\textsf o}$$
$$\newcommand\Sp{\textsf p}$$
$$\newcommand\Sq{\textsf q}$$
$$\newcommand\Sr{\textsf r}$$
$$\newcommand\Ss{\textsf s}$$
$$\newcommand\St{\textsf t}$$
$$\newcommand\Su{\textsf u}$$
$$\newcommand\Sv{\textsf v}$$
$$\newcommand\Sw{\textsf w}$$
$$\newcommand\Sx{\textsf x}$$
$$\newcommand\Sy{\textsf y}$$
$$\newcommand\Sz{\textsf z}$$
$$\newcommand\SA{\textsf A}$$
$$\newcommand\SB{\textsf B}$$
$$\newcommand\SC{\textsf C}$$
$$\newcommand\SD{\textsf D}$$
$$\newcommand\SE{\textsf E}$$
$$\newcommand\SF{\textsf F}$$
$$\newcommand\SG{\textsf G}$$
$$\newcommand\SH{\textsf H}$$
$$\newcommand\SI{\textsf I}$$
$$\newcommand\SJ{\textsf J}$$
$$\newcommand\SK{\textsf K}$$
$$\newcommand\SL{\textsf L}$$
$$\newcommand\SM{\textsf M}$$
$$\newcommand\SN{\textsf N}$$
$$\newcommand\SO{\textsf O}$$
$$\newcommand\SP{\textsf P}$$
$$\newcommand\SQ{\textsf Q}$$
$$\newcommand\SR{\textsf R}$$
$$\newcommand\SS{\textsf S}$$
$$\newcommand\ST{\textsf T}$$
$$\newcommand\SU{\textsf U}$$
$$\newcommand\SV{\textsf V}$$
$$\newcommand\SW{\textsf W}$$
$$\newcommand\SX{\textsf X}$$
$$\newcommand\SY{\textsf Y}$$
$$\newcommand\SZ{\textsf Z}$$
$$\newcommand\Ha{\hat a}$$
$$\newcommand\Hb{\hat b}$$
$$\newcommand\Hc{\hat c}$$
$$\newcommand\Hd{\hat d}$$
$$\newcommand\He{\hat e}$$
$$\newcommand\Hf{\hat f}$$
$$\newcommand\Hg{\hat g}$$
$$\newcommand\Hh{\hat h}$$
$$\newcommand\Hi{\hat \imath}$$
$$\newcommand\Hj{\hat \jmath}$$
$$\newcommand\Hk{\hat k}$$
$$\newcommand\Hl{\hat l}$$
$$\newcommand\Hm{\hat m}$$
$$\newcommand\Hn{\hat n}$$
$$\newcommand\Ho{\hat o}$$
$$\newcommand\Hp{\hat p}$$
$$\newcommand\Hq{\hat q}$$
$$\newcommand\Hr{\hat r}$$
$$\newcommand\Hs{\hat s}$$
$$\newcommand\Ht{\hat t}$$
$$\newcommand\Hu{\hat u}$$
$$\newcommand\Hv{\hat v}$$
$$\newcommand\Hw{\hat w}$$
$$\newcommand\Hx{\hat x}$$
$$\newcommand\Hy{\hat y}$$
$$\newcommand\Hz{\hat z}$$
$$\newcommand\HA{\hat A}$$
$$\newcommand\HB{\hat B}$$
$$\newcommand\HC{\hat C}$$
$$\newcommand\HD{\hat D}$$
$$\newcommand\HE{\hat E}$$
$$\newcommand\HF{\hat F}$$
$$\newcommand\HG{\hat G}$$
$$\newcommand\HH{\hat H}$$
$$\newcommand\HI{\hat I}$$
$$\newcommand\HJ{\hat J}$$
$$\newcommand\HK{\hat K}$$
$$\newcommand\HL{\hat L}$$
$$\newcommand\HM{\hat M}$$
$$\newcommand\HN{\hat N}$$
$$\newcommand\HO{\hat O}$$
$$\newcommand\HP{\hat P}$$
$$\newcommand\HQ{\hat Q}$$
$$\newcommand\HR{\hat R}$$
$$\newcommand\HS{\hat S}$$
$$\newcommand\HT{\hat T}$$
$$\newcommand\HU{\hat U}$$
$$\newcommand\HV{\hat V}$$
$$\newcommand\HW{\hat W}$$
$$\newcommand\HX{\hat X}$$
$$\newcommand\HY{\hat Y}$$
$$\newcommand\HZ{\hat Z}$$
$$\newcommand\Halpha{\hat\alpha}$$
$$\newcommand\Hbeta{\hat\beta}$$
$$\newcommand\Hgamma{\hat\gamma}$$
$$\newcommand\Hdelta{\hat\delta}$$
$$\newcommand\Hepsilon{\hat\epsilon}$$
$$\newcommand\Hvarepsilon{\hat\varepsilon}$$
$$\newcommand\Hzeta{\hat\zeta}$$
$$\newcommand\Heta{\hat\eta}$$
$$\newcommand\Htheta{\hat\theta}$$
$$\newcommand\Hvartheta{\hat\vartheta}$$
$$\newcommand\Hiota{\hat\iota}$$
$$\newcommand\Hkappa{\hat\kappa}$$
$$\newcommand\Hlambda{\hat\lambda}$$
$$\newcommand\Hmu{\hat\mu}$$
$$\newcommand\Hnu{\hat\nu}$$
$$\newcommand\Hxi{\hat\xi}$$
$$\newcommand\Hom{\hat\omicron}$$
$$\newcommand\Hpi{\hat\pi}$$
$$\newcommand\Hvarpi{\hat\varpi}$$
$$\newcommand\Hrho{\hat\rho}$$
$$\newcommand\Hvarrho{\hat\varrho}$$
$$\newcommand\Hsigma{\hat\sigma}$$
$$\newcommand\Hvarsigma{\hat\varsigma}$$
$$\newcommand\Htau{\var\tau}$$
$$\newcommand\Hupsilon{\hat\upsilon}$$
$$\newcommand\Hphi{\hat\phi}$$
$$\newcommand\Hvarphi{\hat\varphi}$$
$$\newcommand\Hchi{\hat\chi}$$
$$\newcommand\Hxhi{\hat\xhi}$$
$$\newcommand\Hpsi{\hat\psi}$$
$$\newcommand\Homega{\hat\omega}$$
$$\newcommand\HGamma{\hat\Gamma}$$
$$\newcommand\HDelta{\hat\Delta}$$
$$\newcommand\HTheta{\hat\Theta}$$
$$\newcommand\HLambda{\hat\Lambda}$$
$$\newcommand\HXi{\hat\Xi}$$
$$\newcommand\HPi{\hat\Pi}$$
$$\newcommand\HSigma{\hat\Sigma}$$
$$\newcommand\HUps{\hat\Upsilon}$$
$$\newcommand\HPhi{\hat\Phi}$$
$$\newcommand\HPsi{\hat\Psi}$$
$$\newcommand\HOmega{\hat\Omega}$$
$$\newcommand\xhat{\hat\Bx}$$
$$\newcommand\yhat{\hat\By}$$
$$\newcommand\zhat{\hat\Bz}$$
$$\newcommand\ehat{\hat\Be}$$
$$\newcommand\khat{\hat\Bk}$$
$$\newcommand\nhat{\hat\Bn}$$
$$\newcommand\rhat{\hat\Br}$$
$$\newcommand\phihat{\hat\Bphi}$$
$$\newcommand\thetahat{\hat\Btheta}$$
$$\newcommand\MA{\mathbb A}$$
$$\newcommand\MB{\mathbb B}$$
$$\newcommand\MC{\mathbb C}$$
$$\newcommand\MD{\mathbb D}$$
$$\newcommand\ME{\mathbb E}$$
$$\newcommand\MF{\mathbb F}$$
$$\newcommand\MG{\mathbb G}$$
$$\newcommand\MH{\mathbb H}$$
$$\newcommand\MI{\mathbb I}$$
$$\newcommand\MJ{\mathbb J}$$
$$\newcommand\MK{\mathbb K}$$
$$\newcommand\ML{\mathbb L}$$
$$\newcommand\MM{\mathbb M}$$
$$\newcommand\MN{\mathbb N}$$
$$\newcommand\MO{\mathbb O}$$
$$\newcommand\MP{\mathbb P}$$
$$\newcommand\MQ{\mathbb Q}$$
$$\newcommand\MR{\mathbb R}$$
$$\newcommand\MS{\mathbb S}$$
$$\newcommand\MT{\mathbb T}$$
$$\newcommand\MU{\mathbb U}$$
$$\newcommand\MV{\mathbb V}$$
$$\newcommand\MW{\mathbb W}$$
$$\newcommand\MX{\mathbb X}$$
$$\newcommand\MY{\mathbb Y}$$
$$\newcommand\MZ{\mathbb Z}$$
$$\newcommand\CA{\mathcal A}$$
$$\newcommand\CB{\mathcal B}$$
$$\newcommand\CC{\mathcal C}$$
$$\newcommand\CD{\mathcal D}$$
$$\newcommand\CE{\mathcal E}$$
$$\newcommand\CF{\mathcal F}$$
$$\newcommand\CG{\mathcal G}$$
$$\newcommand\CH{\mathcal H}$$
$$\newcommand\CI{\mathcal I}$$
$$\newcommand\CJ{\mathcal J}$$
$$\newcommand\CK{\mathcal K}$$
$$\newcommand\CL{\mathcal L}$$
$$\newcommand\CM{\mathcal M}$$
$$\newcommand\CN{\mathcal N}$$
$$\newcommand\CO{\mathcal O}$$
$$\newcommand\CP{\mathcal P}$$
$$\newcommand\CQ{\mathcal Q}$$
$$\newcommand\CR{\mathcal R}$$
$$\newcommand\CS{\mathcal S}$$
$$\newcommand\CT{\mathcal T}$$
$$\newcommand\CU{\mathcal U}$$
$$\newcommand\CV{\mathcal V}$$
$$\newcommand\CW{\mathcal W}$$
$$\newcommand\CX{\mathcal X}$$
$$\newcommand\CY{\mathcal Y}$$
$$\newcommand\CZ{\mathcal Z}$$
$$\newcommand\Fa{\mathfrak a}$$
$$\newcommand\Fb{\mathfrak b}$$
$$\newcommand\Fc{\mathfrak c}$$
$$\newcommand\Fd{\mathfrak d}$$
$$\newcommand\Fe{\mathfrak e}$$
$$\newcommand\Ff{\mathfrak f}$$
$$\newcommand\Fg{\mathfrak g}$$
$$\newcommand\Fh{\mathfrak h}$$
$$\newcommand\Fi{\mathfrak i}$$
$$\newcommand\Fj{\mathfrak j}$$
$$\newcommand\Fk{\mathfrak k}$$
$$\newcommand\Fl{\mathfrak l}$$
$$\newcommand\Fm{\mathfrak m}$$
$$\newcommand\Fn{\mathfrak n}$$
$$\newcommand\Fo{\mathfrak o}$$
$$\newcommand\Fp{\mathfrak p}$$
$$\newcommand\Fq{\mathfrak q}$$
$$\newcommand\Fr{\mathfrak r}$$
$$\newcommand\Fs{\mathfrak s}$$
$$\newcommand\Ft{\mathfrak t}$$
$$\newcommand\Fu{\mathfrak u}$$
$$\newcommand\Fv{\mathfrak v}$$
$$\newcommand\Fw{\mathfrak w}$$
$$\newcommand\Fx{\mathfrak x}$$
$$\newcommand\Fy{\mathfrak y}$$
$$\newcommand\Fz{\mathfrak z}$$
$$\newcommand\FA{\mathfrak A}$$
$$\newcommand\FB{\mathfrak B}$$
$$\newcommand\FC{\mathfrak C}$$
$$\newcommand\FD{\mathfrak D}$$
$$\newcommand\FE{\mathfrak E}$$
$$\newcommand\FF{\mathfrak F}$$
$$\newcommand\FG{\mathfrak G}$$
$$\newcommand\FH{\mathfrak H}$$
$$\newcommand\FI{\mathfrak I}$$
$$\newcommand\FJ{\mathfrak J}$$
$$\newcommand\FK{\mathfrak K}$$
$$\newcommand\FL{\mathfrak L}$$
$$\newcommand\FM{\mathfrak M}$$
$$\newcommand\FN{\mathfrak N}$$
$$\newcommand\FO{\mathfrak O}$$
$$\newcommand\FP{\mathfrak P}$$
$$\newcommand\FQ{\mathfrak Q}$$
$$\newcommand\FR{\mathfrak R}$$
$$\newcommand\FS{\mathfrak S}$$
$$\newcommand\FT{\mathfrak T}$$
$$\newcommand\FU{\mathfrak U}$$
$$\newcommand\FV{\mathfrak V}$$
$$\newcommand\FW{\mathfrak W}$$
$$\newcommand\FX{\mathfrak X}$$
$$\newcommand\FY{\mathfrak Y}$$
$$\newcommand\FZ{\mathfrak Z}$$
$$\newcommand\Da{\dot a}$$
$$\newcommand\Db{\dot b}$$
$$\newcommand\Dc{\dot c}$$
$$\newcommand\Dd{\dot d}$$
$$\newcommand\De{\dot e}$$
$$\newcommand\Df{\dot f}$$
$$\newcommand\Dg{\dot g}$$
$$\newcommand\Dh{\dot h}$$
$$\newcommand\Di{\dot \imath}$$
$$\newcommand\Dj{\dot \jmath}$$
$$\newcommand\Dk{\dot k}$$
$$\newcommand\Dl{\dot l}$$
$$\newcommand\Dm{\dot m}$$
$$\newcommand\Dn{\dot n}$$
$$\newcommand\Do{\dot o}$$
$$\newcommand\Dp{\dot p}$$
$$\newcommand\Dq{\dot q}$$
$$\newcommand\Dr{\dot r}$$
$$\newcommand\Ds{\dot s}$$
$$\newcommand\Dt{\dot t}$$
$$\newcommand\Du{\dot u}$$
$$\newcommand\Dv{\dot v}$$
$$\newcommand\Dw{\dot w}$$
$$\newcommand\Dx{\dot x}$$
$$\newcommand\Dy{\dot y}$$
$$\newcommand\Dz{\dot z}$$
$$\newcommand\DA{\dot A}$$
$$\newcommand\DB{\dot B}$$
$$\newcommand\DC{\dot C}$$
$$\newcommand\DD{\dot D}$$
$$\newcommand\DE{\dot E}$$
$$\newcommand\DF{\dot F}$$
$$\newcommand\DG{\dot G}$$
$$\newcommand\DH{\dot H}$$
$$\newcommand\DI{\dot I}$$
$$\newcommand\DJ{\dot J}$$
$$\newcommand\DK{\dot K}$$
$$\newcommand\DL{\dot L}$$
$$\newcommand\DM{\dot M}$$
$$\newcommand\DN{\dot N}$$
$$\newcommand\DO{\dot O}$$
$$\newcommand\DP{\dot P}$$
$$\newcommand\DQ{\dot Q}$$
$$\newcommand\DR{\dot R}$$
$$\newcommand\DS{\dot S}$$
$$\newcommand\DT{\dot T}$$
$$\newcommand\DU{\dot U}$$
$$\newcommand\DV{\dot V}$$
$$\newcommand\DW{\dot W}$$
$$\newcommand\DX{\dot X}$$
$$\newcommand\DY{\dot Y}$$
$$\newcommand\DZ{\dot Z}$$
$$\newcommand\Dalpha ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[1], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Dbeta ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[2], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Dgamma ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[3], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Ddelta ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[4], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Depsilon ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[5], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Dvarepsilon ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[6], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Dzeta ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[7], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Deta ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[8], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Dtheta ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[9], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Dvartheta ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[10], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Diota ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[11], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Dkappa ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[12], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Dlambda ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[13], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Dmu{\dot\mu}$$
$$\newcommand\Dnu{\dot\nu}$$
$$\newcommand\Dxi{\dot\xi}$$
$$\newcommand\Dom{\dot\omicron}$$
$$\newcommand\Dpi{\dot\pi}$$
$$\newcommand\Dvarpi ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[14], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Drho{\dot\rho}$$
$$\newcommand\Dvarrho{\dot\varrho}$$
$$\newcommand\Dsigma{\dot\sigma}$$
$$\newcommand\Dvarsigma{\dot\varsigma}$$
$$\newcommand\Dtau{\var\tau}$$
$$\newcommand\Dupsilon{\dot\upsilon}$$
$$\newcommand\Dphi{\dot\phi}$$
$$\newcommand\Dvarphi{\dot\varphi}$$
$$\newcommand\Dchi{\dot\chi}$$
$$\newcommand\Dpsi{\dot\psi}$$
$$\newcommand\Domega{\dot\omega}$$
$$\newcommand\DGamma ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[15], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\DDelta ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[16], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\DTheta ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[17], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\DLambda{\dot\Lambda}$$
$$\newcommand\DXi{\dot\Xi}$$
$$\newcommand\DPi{\dot\Pi}$$
$$\newcommand\DSigma{\dot\Sigma}$$
$$\newcommand\DUps{\dot\Upsilon}$$
$$\newcommand\DPhi{\dot\Phi}$$
$$\newcommand\DPsi{\dot\Psi}$$
$$\newcommand\DOmega{\dot\Omega}$$
$$\newcommand\Va{\vec a}$$
$$\newcommand\Vb{\vec b}$$
$$\newcommand\Vc{\vec c}$$
$$\newcommand\Vd{\vec d}$$
$$\newcommand\Ve{\vec e}$$
$$\newcommand\Vf{\vec f}$$
$$\newcommand\Vg{\vec g}$$
$$\newcommand\Vh{\vec h}$$
$$\newcommand\Vi{\vec \imath}$$
$$\newcommand\Vj{\vec \jmath}$$
$$\newcommand\Vk{\vec k}$$
$$\newcommand\Vl{\vec l}$$
$$\newcommand\Vm{\vec m}$$
$$\newcommand\Vn{\vec n}$$
$$\newcommand\Vo{\vec o}$$
$$\newcommand\Vp{\vec p}$$
$$\newcommand\Vq{\vec q}$$
$$\newcommand\Vr{\vec r}$$
$$\newcommand\Vs{\vec s}$$
$$\newcommand\Vt{\vec t}$$
$$\newcommand\Vu{\vec u}$$
$$\newcommand\Vv{\vec v}$$
$$\newcommand\Vw{\vec w}$$
$$\newcommand\Vx{\vec x}$$
$$\newcommand\Vy{\vec y}$$
$$\newcommand\Vz{\vec z}$$
$$\newcommand\VA{\vec A}$$
$$\newcommand\VB{\vec B}$$
$$\newcommand\VC{\vec C}$$
$$\newcommand\VD{\vec D}$$
$$\newcommand\VE{\vec E}$$
$$\newcommand\VF{\vec F}$$
$$\newcommand\VG{\vec G}$$
$$\newcommand\VH{\vec H}$$
$$\newcommand\VI{\vec I}$$
$$\newcommand\VJ{\vec J}$$
$$\newcommand\VK{\vec K}$$
$$\newcommand\VL{\vec L}$$
$$\newcommand\VM{\vec M}$$
$$\newcommand\VN{\vec N}$$
$$\newcommand\VO{\vec O}$$
$$\newcommand\VP{\vec P}$$
$$\newcommand\VQ{\vec Q}$$
$$\newcommand\VR{\vec R}$$
$$\newcommand\VS{\vec S}$$
$$\newcommand\VT{\vec T}$$
$$\newcommand\VU{\vec U}$$
$$\newcommand\VV{\vec V}$$
$$\newcommand\VW{\vec W}$$
$$\newcommand\VX{\vec X}$$
$$\newcommand\VY{\vec Y}$$
$$\newcommand\VZ{\vec Z}$$
$$\newcommand\Valpha{\vec\alpha}$$
$$\newcommand\Vbeta{\vec\beta}$$
$$\newcommand\Vgamma{\vec\gamma}$$
$$\newcommand\Vdelta{\vec\delta}$$
$$\newcommand\Vepsilon{\vec\epsilon}$$
$$\newcommand\Vvarepsilon{\vec\varepsilon}$$
$$\newcommand\Vzeta{\vec\zeta}$$
$$\newcommand\Veta{\vec\eta}$$
$$\newcommand\Vtheta{\vec\theta}$$
$$\newcommand\Vvartheta{\vec\vartheta}$$
$$\newcommand\Viota{\vec\iota}$$
$$\newcommand\Vkappa{\vec\kappa}$$
$$\newcommand\Vlambda{\vec\lambda}$$
$$\newcommand\Vmu ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[18], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Vnu ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[19], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Vxi ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[20], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Vom ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[21], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Vpi ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[22], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Vvarpi ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[23], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Vrho ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[24], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Vvarrho ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[25], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Vsigma ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[26], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Vvarsigma ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[27], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Vtau ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[28], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Vupsilon ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[29], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Vphi ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[30], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Vvarphi ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[31], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Vchi ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[32], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Vpsi ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[33], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\Vomega ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[34], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\VGamma ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[35], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\VDelta ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/p[1]/span[36], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\VTheta{\vec\Theta}$$
$$\newcommand\VLambda{\vec\Lambda}$$
$$\newcommand\VXi{\vec\Xi}$$
$$\newcommand\VPi{\vec\Pi}$$
$$\newcommand\VSigma{\vec\Sigma}$$
$$\newcommand\VUps{\vec\Upsilon}$$
$$\newcommand\VPhi{\vec\Phi}$$
$$\newcommand\VPsi{\vec\Psi}$$
$$\newcommand\VOmega{\vec\Omega}$$
$$\newcommand\BA{\mib A}$$
$$\newcommand\BB{\mib B}$$
$$\newcommand\BC{\mib C}$$
$$\newcommand\BD{\mib D}$$
$$\newcommand\BE{\mib E}$$
$$\newcommand\BF{\mib F}$$
$$\newcommand\BG{\mib G}$$
$$\newcommand\BH{\mib H}$$
$$\newcommand\BI{\mib I}}$$
$$\newcommand\BJ{\mib J}$$
$$\newcommand\BK{\mib K}$$
$$\newcommand\BL{\mib L}$$
$$\newcommand\BM{\mib M}$$
$$\newcommand\BN{\mib N}$$
$$\newcommand\BO{\mib O}$$
$$\newcommand\BP{\mib P}$$
$$\newcommand\BQ{\mib Q}$$
$$\newcommand\BR{\mib R}$$
$$\newcommand\BS{\mib S}$$
$$\newcommand\BT{\mib T}$$
$$\newcommand\BU{\mib U}$$
$$\newcommand\BV{\mib V}$$
$$\newcommand\BW{\mib W}$$
$$\newcommand\BX{\mib X}$$
$$\newcommand\BY{\mib Y}$$
$$\newcommand\BZ{\mib Z}$$
$$\newcommand\Ba{\mib a}$$
$$\newcommand\Bb{\mib b}$$
$$\newcommand\Bc{\mib c}$$
$$\newcommand\Bd{\mib d}$$
$$\newcommand\Be{\mib e}$$
$$\newcommand\Bf{\mib f}$$
$$\newcommand\Bg{\mib g}$$
$$\newcommand\Bh{\mib h}$$
$$\newcommand\Bi{\mib i}$$
$$\newcommand\Bj{\mib j}$$
$$\newcommand\Bk{\mib k}$$
$$\newcommand\Bl{\mib l}$$
$$\newcommand\Bm{\mib m}$$
$$\newcommand\Bn{\mib n}$$
$$\newcommand\Bo{\mib o}$$
$$\newcommand\Bp{\mib p}$$
$$\newcommand\Bq{\mib q}$$
$$\newcommand\Br{\mib r}$$
$$\newcommand\Bs{\mib s}$$
$$\newcommand\Bt{\mib t}$$
$$\newcommand\Bu{\mib u}$$
$$\newcommand\Bv{\mib v}$$
$$\newcommand\Bw{\mib w}$$
$$\newcommand\Bx{\mib x}$$
$$\newcommand\By{\mib y}$$
$$\newcommand\Bz{\mib z}$$\)
$$\newcommand\vrh{\varrho}$$
$$\newcommand\vsig{\varsigma}$$
$$\newcommand\ups{\upsilon}$$
$$\newcommand\eps{\epsilon}$$
$$\newcommand\ve{\varepsilon}$$
$$\newcommand\vth{\vartheta}$$
$$\newcommand\vphi{\varphi}$$
$$\newcommand\xhi{\chi}$$
$$\newcommand\Ups{\Upsilon}$$
$$\newcommand\Balpha{\mib\alpha}$$
$$\newcommand\Bbeta{\mib\beta}$$
$$\newcommand\Bgamma{\mib\gamma}$$
$$\newcommand\Bdelta{\mib\delta}$$
$$\newcommand\Beps{\mib\epsilon}$$
$$\newcommand\Bve{\mib\varepsilon}$$
$$\newcommand\Bzeta{\mib\zeta}$$
$$\newcommand\Beta{\mib\eta}$$
$$\newcommand\Btheta{\mib\theta}$$
$$\newcommand\Bvth{\mib\vartheta}$$
$$\newcommand\Biota{\mib\iota}$$
$$\newcommand\Bkappa{\mib\kappa}$$
$$\newcommand\Blambda{\mib\lambda}$$
$$\newcommand\Bmu{\mib\mu}$$
$$\newcommand\Bnu{\mib\nu}$$
$$\newcommand\Bxi{\mib\xi}$$
$$\newcommand\Bom{\mib\omicron}$$
$$\newcommand\Bpi{\mib\pi}$$
$$\newcommand\Bvarpi{\mib\varpi}$$
$$\newcommand\Brho{\mib\rho}$$
$$\newcommand\Bvrh{\mib\varrho}$$
$$\newcommand\Bsigma{\mib\sigma}$$
$$\newcommand\Bvsig{\mib\varsigma}$$
$$\newcommand\Btau{\mib\tau}$$
$$\newcommand\Bups{\mib\upsilon}$$
$$\newcommand\Bphi{\mib\phi}$$
$$\newcommand\Bvphi{\mib\vphi}$$
$$\newcommand\Bchi{\mib\chi}$$
$$\newcommand\Bpsi{\mib\psi}$$
$$\newcommand\Bomega{\mib\omega}$$
$$\newcommand\BGamma{\mib\Gamma}$$
$$\newcommand\BDelta{\mib\Delta}$$
$$\newcommand\BTheta{\mib\Theta}$$
$$\newcommand\BLambda{\mib\Lambda}$$
$$\newcommand\BXi{\mib\Xi}$$
$$\newcommand\BPi{\mib\Pi}$$
$$\newcommand\BSigma{\mib\Sigma}$$
$$\newcommand\BUps{\mib\Upsilon}$$
$$\newcommand\BPhi{\mib\Phi}$$
$$\newcommand\BPsi{\mib\Psi}$$
$$\newcommand\BOmega{\mib\Omega}$$
$$\newcommand\Bxhi{\raise.35ex\hbox{\Bchi}}$$
$$\newcommand\RGamma{ \Gamma}$$
$$\newcommand\RDelta{ \Delta}$$
$$\newcommand\RTheta{ \Theta}$$
$$\newcommand\RLambda{ \Lambda}$$
$$\newcommand\RXi{ \Xi}$$
$$\newcommand\RPi{ \Pi}$$
$$\newcommand\RSigma{ \Sigma}$$
$$\newcommand\RUps{ \Upsilon}$$
$$\newcommand\RPhi{ \Phi}$$
$$\newcommand\RPsi{ \Psi}$$
$$\newcommand\ROmega{ \Omega}$$
$$\newcommand\RA{ A}$$
$$\newcommand\RB{ B}$$
$$\newcommand\RC{ C}$$
$$\newcommand\RD{ D}$$
$$\newcommand\RE{ E}$$
$$\newcommand\RF{ F}$$
$$\newcommand\RG{ G}$$
$$\newcommand\RH{ H}$$
$$\newcommand\RI{ I}$$
$$\newcommand\RJ{ J}$$
$$\newcommand\RK{ K}$$
$$\newcommand\RL{ L}$$
$$\newcommand { M}$$
$$\newcommand\RN{ N}$$
$$\newcommand\RO{ O}$$
$$\newcommand\RP{ P}$$
$$\newcommand\RQ{ Q}$$
$$\newcommand\RR{ R}$$
$$\newcommand\RS{ S}$$
$$\newcommand\RT{ T}$$
$$\newcommand\RU{ U}$$
$$\newcommand\RV{ V}$$
$$\newcommand\RW{ W}$$
$$\newcommand\RX{ X}$$
$$\newcommand\RY{ Y}$$
$$\newcommand\RZ{ Z}$$
$$\newcommand\Ra{ a}$$
$$\newcommand\Rb{ b}$$
$$\newcommand\Rc{ c}$$
$$\newcommand\Rd{ d}$$
$$\newcommand\Re{ e}$$
$$\newcommand\Rf{ f}$$
$$\newcommand\Rg{ g}$$
$$\newcommand\Rh{ h}$$
$$\newcommand\Ri{ i}$$
$$\newcommand\Rj{ j}$$
$$\newcommand\Rk{ k}$$
$$\newcommand\Rl{ l}$$
$$\newcommand { m}$$
$$\newcommand\Rn{ n}$$
$$\newcommand\Ro{ o}$$
$$\newcommand\Rp{ p}$$
$$\newcommand\Rq{ q}$$
$$\newcommand\Rr{ r}$$
$$\newcommand\Rs{ s}$$
$$\newcommand\Rt{ t}$$
$$\newcommand\Ru{ u}$$
$$\newcommand\Rv{ v}$$
$$\newcommand\Rw{ w}$$
$$\newcommand\Rx{ x}$$
$$\newcommand\Ry{ y}$$
$$\newcommand\Rz{ z}$$
$$\newcommand\BBA{\boldsymbol\RA}$$
$$\newcommand\BBB{\boldsymbol\RB}$$
$$\newcommand\BBC{\boldsymbol\RC}$$
$$\newcommand\BBD{\boldsymbol\RD}$$
$$\newcommand\BBE{\boldsymbol\RE}$$
$$\newcommand\BBF{\boldsymbol\RF}$$
$$\newcommand\BBG{\boldsymbol\RG}$$
$$\newcommand\BBH{\boldsymbol\RH}$$
$$\newcommand\BBI{\boldsymbol\RI}$$
$$\newcommand\BBJ{\boldsymbol\RJ}$$
$$\newcommand\BBK{\boldsymbol\RK}$$
$$\newcommand\BBL{\boldsymbol\RL}$$
$$\newcommand\BBM{\boldsymbol }$$
$$\newcommand\BBN{\boldsymbol\RN}$$
$$\newcommand\BBO{\boldsymbol\RO}$$
$$\newcommand\BBP{\boldsymbol\RP}$$
$$\newcommand\BBQ{\boldsymbol\RQ}$$
$$\newcommand\BBR{\boldsymbol\RR}$$
$$\newcommand\BBS{\boldsymbol\RS}$$
$$\newcommand\BBT{\boldsymbol\RT}$$
$$\newcommand\BBU{\boldsymbol\RU}$$
$$\newcommand\BBV{\boldsymbol\RV}$$
$$\newcommand\BBW{\boldsymbol\RW}$$
$$\newcommand\BBX{\boldsymbol\RX}$$
$$\newcommand\BBY{\boldsymbol\RY}$$
$$\newcommand\BBZ{\boldsymbol\RZ}$$
$$\newcommand\BBa{\boldsymbol\Ra}$$
$$\newcommand\BBb{\boldsymbol\Rb}$$
$$\newcommand\BBc{\boldsymbol\Rc}$$
$$\newcommand\BBd{\boldsymbol\Rd}$$
$$\newcommand\BBe{\boldsymbol\Re}$$
$$\newcommand\BBf{\boldsymbol\Rf}$$
$$\newcommand\BBg{\boldsymbol\Rg}$$
$$\newcommand\BBh{\boldsymbol\Rh}\}$$
$$\newcommand\BBi{\boldsymbol\Ri}$$
$$\newcommand\BBj{\boldsymbol\Rj}$$
$$\newcommand\BBk{\boldsymbol\Rk}$$
$$\newcommand\BBl{boldsymbol\Rl}$$
$$\newcommand\BBm{\boldsymbol }$$
$$\newcommand\BBn{\boldsymbol\Rn}$$
$$\newcommand\BBo{\boldsymbol\Ro}$$
$$\newcommand\BBp{\boldsymbol\Rp}$$
$$\newcommand\BBq{\boldsymbol\Rq}$$
$$\newcommand\BBr{\boldsymbol\Rr}$$
$$\newcommand\BBs{\boldsymbol\Rs}$$
$$\newcommand\BBt{\boldsymbol\Rt}$$
$$\newcommand\BBu{\boldsymbol\Ru}$$
$$\newcommand\BBv{\boldsymbol\Rv}$$
$$\newcommand\BBw{\boldsymbol\Rw}$$
$$\newcommand\BBx{\boldsymbol\Rx}$$
$$\newcommand\BBy{\boldsymbol\Ry}$$
$$\newcommand\BBz{\boldsymbol\Rz}$$
$$\newcommand\tcb{\textcolor{blue}$$
$$\newcommand\tcr{\textcolor{red}$$
$$\newcommand\bnabla{\boldsymbol{\nabla}}$$
$$\newcommand\Bell{\boldsymbol\ell}$$
$$\newcommand\dbar{\,{\mathchar'26\mkern-12mu d}}$$
$$\newcommand\ns{^\vphantom{*}}$$
$$\newcommand\uar{\uparrow}$$
$$\newcommand\dar{\downarrow}$$
$$\newcommand\impi{\int\limits_{-\infty}^{\infty}\!\!}$$
$$\newcommand\izpi{\int\limits_{0}^{\infty}\!\!}$$
$$\newcommand\etc{\it etc.\/}$$
$$\newcommand\etal{\it et al.\/}$$
$$\newcommand\opcit{\it op. cit.\/}$$
$$\newcommand\ie{\it i.e.\/}$$
$$\newcommand\Ie{\it I.e.\/}$$
$$\newcommand\viz{\it viz.\/}$$
$$\newcommand\eg{\it e.g.\/}$$
$$\newcommand\Eg{\it E.g.\/}$$
$$\newcommand\dbar{\,{\mathchar'26\mkern-12mu d}}$$
$$\def\sss#1{\scriptscriptstyle #1}$$
$$\def\ss#1{\scriptstyle #1}$$
$$\def\ssr#1{\scriptstyle #1}$$
$$\def\ssf#1{\scriptstyle #1}$$
$$\newcommand\NA{N_{\ssr{\!A}}}$$
$$\newcommand\lala{\langle\!\langle}$$
$$\newcommand\rara{\rangle\!\rangle}$$
$$\newcommand\blan{\big\langle}$$
$$\newcommand\bran{\big\rangle}$$
$$\newcommand\Blan{\Big\langle}$$
$$\newcommand\Bran{\Big\rangle}$$
$$\newcommand\intl{\int\limits}$$
$$\newcommand\half{\frac{1}{2}}$$
$$\newcommand\third{\frac{1}{3}}$$
$$\newcommand\fourth{\frac{1}{4}}$$
$$\newcommand\eighth{\frac{1}{8}}$$
$$\newcommand\uar{\uparrow}$$
$$\newcommand\dar{\downarrow}$$
$$\newcommand\undertext#1{\underline{\hbox{#1}}}$$
$$\newcommand\Tra{\mathop{\textsf{Tr}}\,}$$
$$\newcommand\det{\mathop{\textsf{det}}\,}$$
$$\def\tket#1{| #1 \rangle}$$
$$\def\tbra#1{\langle #1|}$$
$$\def\tbraket#1#2{\langle #1 | #2 \rangle}$$
$$\def\texpect#1#2#3{\langle #1 | #2 | #3 \rangle}$$
$$\def\sket#1{| \, #1 \, \rangle}$$
$$\def\sbra#1{\langle \, #1 \, |}$$
$$\def\sbraket#1#2{\langle \, #1 \, | \, #2 \, \rangle}$$
$$\def\sexpect#1#2#3{\langle \, #1 \, | \, #2 \, | \, #3 \, \rangle}$$
$$\def\ket#1{\big| \, #1\, \big\rangle}$$
$$\def\bra#1{\big\langle \, #1 \, \big|}$$
$$\def\braket#1#2{\big\langle \, #1\, \big| \,#2 \,\big\rangle}$$
$$\def\expect#1#2#3{\big\langle\, #1\, \big|\, #2\, \big| \,#3\, \big\rangle}$$
$$\newcommand\pz{\partial}$$
$$\newcommand\pzb{\bar{\partial}}$$
$$\newcommand\svph{\vphantom{\int}}$$
$$\newcommand\vph{\vphantom{\sum_i}}$$
$$\newcommand\bvph{\vphantom{\sum_N^N}}$$
$$\newcommand\nd{^{\vphantom{\dagger}}}$$
$$\newcommand\ns{^{\vphantom{*}}}$$
$$\newcommand\yd{^\dagger}$$
$$\newcommand\zb{\bar z}$$
$$\newcommand\zdot{\dot z}$$
$$\newcommand\zbdot{\dot{\bar z}}$$
$$\newcommand\kB{k_{\sss{B}}}$$
$$\newcommand\kT{k_{\sss{B}}T}$$
$$\newcommand\gtau{g_\tau}$$
$$\newcommand\Htil{\tilde H}$$
$$\newcommand\pairo{(\phi\nd_0,J\nd_0)}$$
$$\newcommand\pairm{(\phi\nd_0,J)}$$
$$\newcommand\pairob{(\Bphi\nd_0,\BJ\nd_0)}$$
$$\newcommand\pairmb{(\Bphi\nd_0,\BJ)}$$
$$\newcommand\pair{(\phi,J)}$$
$$\newcommand\Hz{H\nd_0}$$
$$\newcommand\Ho{H\nd_1}$$
$$\newcommand\Htz{\Htil\nd_0}$$
$$\newcommand\Hto{\Htil\nd_1}$$
$$\newcommand\oc{\omega_\Rc}$$

$$\newcommand \gtwid{\approx}$$

$$\newcommand\index{\textsf{ind}}$$
$$\newcommand\csch{\,{ csch\,}}$$
$$\newcommand\ctnh{\,{ ctnh\,}}$$
$$\newcommand\ctn{\,{ ctn\,}}$$
$$\newcommand\sgn{\,{ sgn\,}}$$
$$\def\tmapright#1{\xrightarrow \limits^{#1}}$$
$$\def\bmapright#1{\xrightarrow\limits_{#1}}$$
$$\newcommand\hfb{\hfill\break}$$
$$\newcommand\Rep{\textsf{Re}\,}$$
$$\newcommand\Imp{\textsf{Im}\,}$$
$$\newcommand\ncdot{\!\cdot\!}$$
$$\def\tmapright#1{ \smash{\mathop{\hbox to 35pt{\rightarrowfill}}\limits^{#1}}\ }$$
$$\def\bmapright#1{ \smash{\mathop{\hbox to 35pt{\rightarrowfill}}\limits_{#1}}\ }$$
$$\newcommand\bsqcap{\mbox{\boldmath{\sqcap}}}$$

$$\def\pabc#1#2#3{\left({\pz #1\over\pz #2}\right)\ns_{\!\!#3}}$$
$$\def\spabc#1#2#3{\big({\pz #1\over\pz #2}\big)\ns_{\!#3}}$$
$$\def\qabc#1#2#3{\pz^2\! #1\over\pz #2\,\pz #3}$$
$$\def\rabc#1#2#3#4{(\pz #1,\pz #2)\over (\pz #3,\pz #4)}$$
$$\newcommand\subA{\ns_\ssr{A}}$$
$$\newcommand\subB{\ns_\ssr{B}}$$
$$\newcommand\subC{\ns_\ssr{C}}$$
$$\newcommand\subD{\ns_\ssr{D}}$$
$$\newcommand\subAB{\ns_\ssr{AB}}$$
$$\newcommand\subBC{\ns_\ssr{BC}}$$
$$\newcommand\subCD{\ns_\ssr{CD}}$$
$$\newcommand\subDA{\ns_\ssr{DA}}$$
$$\def\lmapright#1{\ \ \smash{\mathop{\hbox to 55pt{\rightarrowfill}}\limits^{#1}}\ \ }$$
$$\def\enth#1{\RDelta {\textsf H}^0_\Rf[{ #1}]}$$
\newcommand\longrightleftharpoons{ \mathop{\vcenter{\hbox{\ooalign{\raise1pt\hbox{\longrightharpoonup\joinrel}\crcr \lower1pt\hbox{\longleftharpoondown\joinrel}}}}}}
$$\newcommand\longrightharpoonup{\relbar\joinrel\rightharpoonup}$$
$$\newcommand\longleftharpoondown{\leftharpoondown\joinrel\relbar}$$
$$\newcommand\cds{\,\bullet\,}$$
$$\newcommand\ccs{\,\circ\,}$$
$$\newcommand\nsub{_{\vphantom{\dagger}}}$$
$$\newcommand\rhohat{\hat\rho}$$
$$\newcommand\vrhhat{\hat\vrh}$$
$$\newcommand\impi{\int\limits_{-\infty}^\infty\!\!\!}$$
$$\newcommand\brangle{\big\rangle}$$
$$\newcommand\blangle{\big\langle}$$
$$\newcommand\vet{\tilde\ve}$$
$$\newcommand\zbar{\bar z}$$
$$\newcommand\ftil{\tilde f}$$
$$\newcommand\XBE{\RXi\ns_\ssr{BE}}$$
$$\newcommand\XFD{\RXi\ns_\ssr{FD}}$$
$$\newcommand\OBE{\Omega\ns_\ssr{BE}}$$
$$\newcommand\OFD{\Omega\ns_\ssr{FD}}$$
$$\newcommand\veF{\ve\ns_\RF}$$
$$\newcommand\kF{k\ns_\RF}$$
$$\newcommand\kFu{k\ns_{\RF\uar}}$$
$$\newcommand\muB{\mu\ns_\ssr{B}}$$
$$\newcommand\mutB{\tilde\mu}\ns_\ssr{B}$$
$$\newcommand\xoN{\Bx\ns_1\,,\,\ldots\,,\,\Bx\ns_N}$$
$$\newcommand\rok{\Br\ns_1\,,\,\ldots\,,\,\Br\ns_k}$$
$$\newcommand\xhiOZ{\xhi^\ssr{OZ}}$$
$$\newcommand\xhihOZ ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/span[1], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\jhz{\HJ(0)}$$
$$\newcommand\nda{\nd_\alpha}$$
$$\newcommand\ndap{\nd_{\alpha'}}$$
$$\newcommand\labar ParseError: invalid DekiScript (click for details) Callstack: at (Template:MathJaxArovas), /content/body/div/span[2], line 1, column 1 at template() at (Bookshelves/Thermodynamics_and_Statistical_Mechanics/Book:_Thermodynamics_and_Statistical_Mechanics_(Arovas)/09:_Renormalization/9.03:_Block_Spin_Transformation), /content/body/p[1]/span, line 1, column 23 $$
$$\newcommand\msa{m\ns_\ssr{A}}$$
$$\newcommand\msb{m\ns_\ssr{B}}$$
$$\newcommand\mss{m\ns_\Rs}$$
$$\newcommand\HBx{\hat\Bx}$$
$$\newcommand\HBy{\hat\By}$$
$$\newcommand\HBz{\hat\Bz}$$
$$\newcommand\thm{\theta\ns_m}$$
$$\newcommand\thp{\theta\ns_\phi}$$
$$\newcommand\mtil{\widetilde m}$$
$$\newcommand\phitil{\widetilde\phi}$$
$$\newcommand\delf{\delta\! f}$$
$$\newcommand\coll{\bigg({\pz f\over\pz t}\bigg)\nd_{\! coll}}$$
$$\newcommand\stre{\bigg({\pz f\over\pz t}\bigg)\nd_{\! str}}$$
$$\newcommand\idrp{\int\!\!{d^3\!r\,d^3\!p\over h^3}\>}$$
$$\newcommand\vbar{\bar v}$$
$$\newcommand\BCE{\mbox{\boldmath{\CE}}\!}$$
$$\newcommand\BCR{\mbox{\boldmath{\CR}}\!}$$
$$\newcommand\gla{g\nd_{\RLambda\nd}}$$
$$\newcommand\TA{T\ns_\ssr{A}}$$
$$\newcommand\TB{T\ns_\ssr{B}}$$
$$\newcommand\ncdot{\!\cdot\!}$$
$$\newcommand\NS{N\ns_{\textsf S}}$$

Spin blocking refers to a process in which we replace a group of spins by a single spin whose direction is determined by ‘majority rule’. That is, if most of the spins in the group are up, then the block spin is said to be up; if most spins are down, then the block spin is down. The block spins interact with a different set of couplings $$\{K'_\alpha\}$$.

Consider a $$b\times b\times\cdots\times b$$ block of spins, and define the block spin projector, $\CT\big(\sigma'_a\,,\,\{\sigma\ns_i\}\big)=\begin{cases} 1 & \hbox{of \sigma'_a={sgn}\left(\sum_{i=1}^{b^d}\sigma\ns_{a,i}\right)}\\ 0 & \hbox{otherwise}\ . \end{cases}$ Note that $\sum_{\sigma\ns_a}\,\CT\big(\sigma'_a\,,\,\{\sigma\ns_{a,i}\}\big)=1 \ .$ Here $$a$$ indexes the blocks, and $$\sigma\ns_{a,i}$$ denotes the $$i^{th}$$ spin within the $$a^{th}$$ block. The block spin projector effects the ‘majority rule’ operation, assigning $$\sigma'_a$$ to $$\pm 1$$ depending on whether the majority of the spins in the block $$a$$ are up ($$\sigma'_a=+1$$) or down ($$\sigma'_a=-1)$$. Note that such a procedure presumes an odd number of spins in each block. Then \begin{aligned} Z&=\sum_{\{\sigma\ns_i\}}e^{-\beta\HH[\{\sigma\ns_i\}]}\nonumber\\ &=\sum_{\{\sigma'_a\}}\left\{\sum_{\{\sigma\ns_i\}} e^{-\beta\HH[\{\sigma\ns_{a.i}\}]}\prod_a\CT\big(\sigma'_a\,,\,\{\sigma\ns_{a,i}\}\big)\right\}\nonumber\\ &=\sum_{\{\sigma'_a\}}e^{-\beta \HH'[\{\sigma'_a\}]}\ ,\end{aligned} where $e^{-\beta \HH'[\{\sigma'_a\}]}=\sum_{\{\sigma\ns_i\}} e^{-\beta\HH[\{\sigma\ns_i\}]} \prod_a \CT\big(\sigma'_a\,,\,\{\sigma\ns_{a,i}\}\big)\ .$


text:
# How to get inline preview of numbered math equations using

RStudio IDE supports inline/tool mathjax equation previews of equations using $or$\$ syntax for RMarkdown documents, e.g.

a^2+b^2=c^2

However, if I want numbered labeled equations in bookdown I need to use LaTeX equation syntax

$$a^2+b^2=c^2 \label{eq:pythagoras}$$

(Typically actually \begin{align})
These are not, AFAICT, previewable. This is vexing because it is precisely these equations which are likely to be complex enough to need preview.

Is this feature on the RStudio roadmap? Or is it perhaps already in there and I just haven't noticed where?

I think this is the first time we've heard this request -- would you mind filing this as a feature request at https://github.com/rstudio/rstudio/issues, so we don't lose track of it?

1 Like

Thanks! Consider the issue open.

I wonder if yihui or the other RMarkdown folks have a workaround?

Or, to turn this idea around, I wonder if it would be a useful feature for knitr/latex documents to also offer preview of the equations in RStudio IDE, i.e. support LaTeX equations in LaTeX documents even.

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.