-
You can write Ox programs to perform calculations like a calculator (or a spreadsheet cell formula) would. Of course, the point of a general purpose mathematical language like Ox is to code elaborate calculations that no calculator could. But understanding basic arithmetic operations available to you in a programming language is the first step toward economic computations.
- Calculator Expressions Consider a mathematical expression:
- $$ { y^2 + \log(z) \over e^{{(3 - yz)}^{-2}} }\tag{A}\label{A}$$
On a calculator you could key this expression as long as you had values to assign to the variables $y$ and $z$. But there would be limitations: you cannot put one expression "over" another to represent division. You would need to use "$/$" to do this. And to compute $yz$ you must use "$*$" or "$\times$". And you would use
^
to represent $y^2$. Another issue is how to implement functions like $\log(x)$ and $e^x$. Typically these are implemented not as operators (like^
) but as named functions. In the case of Ox and nearly every other language the corresponding functions arelog(x)
andexp(x)
. With those concerns in mind, a naive translation of \eqref{A} might look this: Extra whitespace has been put in the formula to make it easier to read. Remember two or more spaces are the same as one space in Ox, and spaces inside expressions are not important. They could all be removed from (A) and the result would be the same. Also, note that this is an Ox expression; it is not a statement yet because there is no(A).1 y^2 + log(z) / exp( (3-y*z)^(-2) )
;
to end it. And the expression would almost certainly be surrounded by more code to, for example, store the results in a variable or to print the result to the screen. To evaluate an expression the calculator or Ox must parse it. For the most part it will parse expressions the way you learn in math. Parsing starts at the left and mostly (moving) right. This requires that operators are carried out in an order. As Ox scans left-to-right it will decide which things get done first then second, etc.Table 2. Basic Arithmetic Operators in Ox
# Class Symbols Note ----------------------------------------------- 1 grouping () [] 2 power ^ 3 signs - + right to left 4 multiplicative * / 5 additive + - 6 assignment = right-to-left
For the most part, this order is exactly as you would expect from the way we write math on paper. For example, when a left bracket "(" is found in the expression, the matching right bracket will be found and then everything inside the bracket will be evaluated before proceeding. On the other hand, when evaluating(A).2 (y^2+ln(z)) / exp( (3-y*z)^-2)
x*y+z*w
the $*$ comes before $+$ sox*y
would be computed first. Then since $*$ has higher priority,z*w
is computed before it is added toxy
. Just as in ordinary math, if you wantedy+z
to be computed you would have to move it up in precedence by writingx*(y+z)*w
. In the case ofx*y^z*w
we see from the table that $\^$ comes before $*$ in precedence, thusx*y^z*w = x*(y^z)*w
not(x*y)^z*w
. But it is a bit dangerous to rely on the precedence in this case since you have to be very confident that^
comes first. I usually err on the safe side and writex*(y^z)*w
rather than relying on operator precedence. Notice that=
is just a low precedent operator (#6 in the table above). Consider two Ox statements: These are not completely different in terms of syntax. Both are valid statements in Ox. And from the table we know that with1. x = y+5; 2. x + y;
x = y+5;
that + is completed before =. Soy+5
will happen and the result will be assigned to x. There is one thing that is very special about=
, however. Namely, the left side of it must be some physical location to store the information on the right. So although4+5;
is not an error in Ox,4=5;
is. That is because 4 is not athing
. It is not a physical spot in your computer memory which can store the value 5. So it is not a left value or lvalue. Ox has several more useful operators to help you code sophisticated mathematical procedures. Further, Ox operators work on matrices. Most non-mathematical languages do notget
matrices, so this is likely new to you even if you have done some programming before. The ability to process matrices in complex ways is one of the most important aspects of Ox, because it makes your code simpler and more efficient. However, like any powerful tool, these extended operators can create errors if you do not understand them before using them in your code. These are discussed later.- Indexing matrices, strings and arrays
To get to elements of a matrix and other things with more than one value (including strings and arrays) your code has to include theindex
to the value. A matrix has two indices, as in $a_{ij}$ being the element of a matrix $A$ in the ith row and jth column. Ox does the same thing, except there is no way to use subscripts in a plain text program. And if you just wroteAij
that looks like an identifier. Instead, each index must be put inside square brackets, soA[i][j]
. Ox is like many languages in that indexing always starts at zero. So the top-left element of a matrix is indexed with[0][0]
. A 2 × 3 matrix has elements:[0][0] [0][1] [0][2] [1][0] [1][1] [1][2]
[i][0]
. And for a row vector it would be[0][i]
. You can always include the[0]
index, but you can drop it and use only one of the index brackets, as shown here: If you index a two-dimensional matrix with only one index Ox will print out a warning and act as if you putdecl v = <0; 1; 2>; v[1] = 4;
v
would now contain0 4 2
[0]
as the second index. along with a warning. The warning should prompt you to putA = <0, 1; 2, 3>; A[1] = 4;
A
would now contain0 1 4 3
[0]
in your code so that you are sure you are changing element $A_{10}$ instead of $A_{01}$.- Prefix and Postfix Incrementation
Prefix
meansplaced before the thing
;postfix
meansplaced after the thing
and incrementation means add or subtract by one. In first generation computer programs (like FORTRAN or COBOL) one of the most common types of statements would be This is incrementing the variablei = i + 1; j = j - 1;
i
. This would typically happen inside a loop, a kind of complex statement introduced below. Anything that is very common and involves the same symbol twice (herei
) is prone to error. The programmer might accidentally typei = j + 1;
and not notice the mistake. So Ox uses the same syntax as C and many other C-based languages to eliminate the need/danger of increments. In Ox you can simply write This meansi++;
add 1 to the current value of
. And you can decrement (subtract 1) usingi
and store it back ini
i--
. The following uses of will create errors (try to understand why): You can also place the value before the thing to be incremented;//ERRORS 5++; decl msg = "hello"; msg++; decl list = {"milk","eggs"}; list--;
Is there a difference? Yes, there is a real difference between++i; --j;
++i
and--i
. You should try to understand the difference yourself by running this program:04a-increments.ox 1: #include "oxstd.h" 2: main() { 3: decl i; 4: i = 5; 5: println("A. ",i); 6: println("B. ",i++); 7: println("C. ",++i); 8: println("D. ",i); 9: println("E. ",--i); 10: println("F. ",i--); 11: println("G. ",i); 12: }
- Transpose The postfix operator
- Logic and Relations Besides computing expressions computational economics needs to compare values, check for conditions based on inputs, etc. This requires ways to carry out logical operations, which means determines whether some condition is true or false. If your model does one thing when $x \lt y$ and another thing when $x\ge y$, then the result of the comparison has to be recorded and remembered. This requires storing the values of
Name Symbol Example Notes on Ox Value Produced ----------------------------------------------------------------------------------------- truth value A FALSE if A=0, TRUE otherwise (any non-zero value) Equality == A==B equals 1 if A=B, 0 otherwise Not Equal != A!=B equals 0 if A=B, 1 otherwise Less Than < A<B Greater Than > A>B Less or Equal <= A<=B Greater or Equal>= A>=B Not ! !A equals 1 if A=0, 1 otherwise And && A&&B 1 if A and B are TRUE, 0 otherwise Or || A||B equals 1 if A or B are TRUE, 0 if both FALSE
'
takes the transpose of a matrix. It has no effect on other arithmetic types of operands. That is, the transpose of an integer or a double is itself.
TRUE
and FALSE
.
One (possibly intuitive) notion is that FALSE
is like the numeric value 0. And TRUE
is like the numerical value 1. This works beautifully and is the basis of Boolean logic. However, what is the truth value of 3? Or -22? In Boolean logic these values cannot occur, but if we try to store truth values in, say, an Ox int
value we might encounter such values. Some languages have a specific type that only stores 0 and 1. In Ox (and many other values), the rule is that 0 is FALSE
and not 0 is TRUE
. In other words, anything but 0 is treated like TRUE. And if you ask Ox to store a TRUE value it will store the value 1.
Table 3. Logic and Relational Operators in Ox
A
or B
is a matrix? What is the logical meaning of $A \le B$ if both sides are matrices? These types of comparisons are explained later.
Exercises
04c-OneTenth.ox 1: #include2: main() { 3: //Step 0. 4: println("1/10 = ",0.1); 5: }
- Augment the program to print out
0.1
four more times based on have 4 different expressions that evaluate to 0.1:- scientific notation (e.g. 2E1=20)
- using
/
in an expression that evaluates to 0.1- using
^
- using
.sqrt()
- Now store 0.1 in a variable
y
. Print out the values of $\ln y$, $y^2$, $y^y$, $1/y$, $e^y$, and $e^{-y^2/2}$. Find the built-in Ox functions and operators necessary. In each case, print out a string to identify the expression, likeprintln("1/y=",1/y);
. - Copy and paste the lines for the previous step's calculations. In between the two copies, re-set the value of $y$ to equal the matrix $\l(\matrix{1&2\cr 3&4}\r)$. Observe what happens when you apply those operators to a matrix. If any of the operators generate an error when applied to a matrix try replacing it with the "dot" version and observe the result.
04b-vecwarn.ox
1: #include "oxstd.h"
2: main() {
3: decl v = <0; 1; 2>;
4: v[1] = 4;
5: println("v=",v);
6: decl A = <0, 1; 2, 3>;
7: A[1] = 4;
8: println("A=",A);
9: }
Am
and Cp
. Print out the text of the grades and the resulting GPA and percentage.
04a-increments.ox
1: #include "oxstd.h"
2: main() {
3: decl i;
4: i = 5;
5: println("A. ",i);
6: println("B. ",i++);
7: println("C. ",++i);
8: println("D. ",i);
9: println("E. ",--i);
10: println("F. ",i--);
11: println("G. ",i);
12: }
5.1 6.2 -1.15 0.2 0.4 0.0 0.0 -3.0 0.0 0.8 1.6 0.0 -9.2 -3.1 2.4
06a-matrix-io.ox
1: #include "oxstd.h"
2: main() {
3: decl m;
4: // create matrix given
5: // save to a file
6: // load matrix back in, print out result
7: }
- Store the matrix in the variable
m
. Look up thesavemat()
function. Use it to save $m$ to a file named m.mat. - Look up
loadmat()
to load the matrix back into another variablem2
. Print outm2
to check that it worked. - Open the file m.mat in Oxedit. Try to understand the format of the file and how it relates to the matrix you saved to it. Then look up the Ox help information for
loadmat()
and see if the explanation for a.mat
matches what you learned from looking at one. - Edit the file m.mat by switching the two numbers on the first line and save the file. Then comment out the
loadmat()
statement so it doesn't happen and re-run to see what happens when you print outm2
.