Forked from anonymous/latin_squares_experimental_design.ipynb
Created
January 12, 2017 18:14
-
-
Save braingineer/5450bd3e1a259bb2a8809fcb1e207324 to your computer and use it in GitHub Desktop.
Latin Squares Experimental Design Generator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "# Latin Square Experimental Design\n\nLatin squares have the property that every number appears before and after every other number and equal number of times. \n\n\nThis makes latin squares useful experimental designs. They can provide a balanced and randomized trial sequence. \n\nI've given an example below. \n\nThe goal of this notebook is to generate a set of pre-made latin squares for javascript experiments. It probably could have been programmed in JS, but I'm faster with python. \n\nI implemented the algorithm [described here](http://rintintin.colorado.edu/~chathach/balancedlatinsquares.html),\nwhich is an instantiation of \n\n\n> `Bradley, J. V. \n> Complete counterbalancing of immediate sequential effects in a Latin square design. \n> Journal of American Statistical Association, 1958, 53, 525-528.`\n\n\n### Note\nThis algorithm only works for even numbers. Odd numbers require some extra trickiness" | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": false | |
}, | |
"cell_type": "code", | |
"source": "generate_one(10)", | |
"execution_count": 2, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": "array([[ 1, 2, 10, 3, 9, 4, 8, 5, 7, 6],\n [ 2, 3, 1, 4, 10, 5, 9, 6, 8, 7],\n [ 3, 4, 2, 5, 1, 6, 10, 7, 9, 8],\n [ 4, 5, 3, 6, 2, 7, 1, 8, 10, 9],\n [ 5, 6, 4, 7, 3, 8, 2, 9, 1, 10],\n [ 6, 7, 5, 8, 4, 9, 3, 10, 2, 1],\n [ 7, 8, 6, 9, 5, 10, 4, 1, 3, 2],\n [ 8, 9, 7, 10, 6, 1, 5, 2, 4, 3],\n [ 9, 10, 8, 1, 7, 2, 6, 3, 5, 4],\n [10, 1, 9, 2, 8, 3, 7, 4, 6, 5]], dtype=int32)" | |
}, | |
"metadata": {}, | |
"execution_count": 2 | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": false | |
}, | |
"cell_type": "code", | |
"source": "print(base.format(\n spacer.join([\n entry_template.format(i, make_matrix(generate_one(i))) for i in range(4,10,2)\n ])\n ))", | |
"execution_count": 5, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": "\nvar latin_squares = {\n\n \"4\": [[ 1, 2, 4, 3],\n [ 2, 3, 1, 4],\n [ 3, 4, 2, 1],\n [ 4, 1, 3, 2]],\n \n \"6\": [[ 1, 2, 6, 3, 5, 4],\n [ 2, 3, 1, 4, 6, 5],\n [ 3, 4, 2, 5, 1, 6],\n [ 4, 5, 3, 6, 2, 1],\n [ 5, 6, 4, 1, 3, 2],\n [ 6, 1, 5, 2, 4, 3]],\n \n \"8\": [[ 1, 2, 8, 3, 7, 4, 6, 5],\n [ 2, 3, 1, 4, 8, 5, 7, 6],\n [ 3, 4, 2, 5, 1, 6, 8, 7],\n [ 4, 5, 3, 6, 2, 7, 1, 8],\n [ 5, 6, 4, 7, 3, 8, 2, 1],\n [ 6, 7, 5, 8, 4, 1, 3, 2],\n [ 7, 8, 6, 1, 5, 2, 4, 3],\n [ 8, 1, 7, 2, 6, 3, 5, 4]]\n}\n\n", | |
"name": "stdout" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": true | |
}, | |
"cell_type": "code", | |
"source": "import numpy as np\n\ndef generate_one(n):\n out = np.empty((n,n)).astype(np.int32)\n out[0, 0] = 1\n forward = list(range(1, n, 2))\n backward = sorted(set(range(1,n))-set(forward), reverse=True)\n \n for latin_number, index in enumerate(forward+backward, 2):\n out[0, index] = latin_number\n for column_index in range(n):\n out[1:, column_index] = np.arange(out[0, column_index]+1, out[0, column_index] + n) % n\n out[out==0] = n\n return out\n\nbase = \"\"\"\nvar latin_squares = {{\n{}\n}}\n\"\"\"\n\nentry_template = \"\"\"\n \"{}\": {}\"\"\"\n\nspacer = \"\"\",\n \"\"\"\n\nrow_template = \"[{}]\"\n\nmake_row = lambda row: row_template.format(\", \".join([\"{:>2}\".format(i) for i in row]))\nmake_matrix = lambda mat:\"[\"+spacer.join([make_row(mat[i]) \n for i in range(mat.shape[0])])+\"]\"\n\nfilepath = \"latin_squares.js\"\nwith open(filepath, \"w\") as fp:\n fp.write(base.format(\n spacer.join([\n entry_template.format(i, make_matrix(generate_one(i))) for i in range(4,40,2)\n ])\n ))", | |
"execution_count": 6, | |
"outputs": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"name": "conda-env-DL-py", | |
"display_name": "Python [conda env:DL]", | |
"language": "python" | |
}, | |
"language_info": { | |
"mimetype": "text/x-python", | |
"nbconvert_exporter": "python", | |
"name": "python", | |
"pygments_lexer": "ipython2", | |
"version": "2.7.11", | |
"file_extension": ".py", | |
"codemirror_mode": { | |
"version": 2, | |
"name": "ipython" | |
} | |
}, | |
"gist": { | |
"id": "f3cdaf92f5b835dc08fd22255dad21f5", | |
"data": { | |
"description": "Latin Squares Experimental Design Generator", | |
"public": true | |
} | |
}, | |
"_draft": { | |
"nbviewer_url": "https://gist.github.com/f3cdaf92f5b835dc08fd22255dad21f5" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 1 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment