GNU Octave
3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
Main Page
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Pages
libinterp
parse-tree
pt-cbinop.cc
Go to the documentation of this file.
1
/*
2
3
Copyright (C) 2008-2013 Jaroslav Hajek
4
5
This file is part of Octave.
6
7
Octave is free software; you can redistribute it and/or modify it
8
under the terms of the GNU General Public License as published by the
9
Free Software Foundation; either version 3 of the License, or (at your
10
option) any later version.
11
12
Octave is distributed in the hope that it will be useful, but WITHOUT
13
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15
for more details.
16
17
You should have received a copy of the GNU General Public License
18
along with Octave; see the file COPYING. If not, see
19
<http://www.gnu.org/licenses/>.
20
21
*/
22
23
#ifdef HAVE_CONFIG_H
24
#include <config.h>
25
#endif
26
27
#include "
error.h
"
28
#include "
oct-obj.h
"
29
#include "
ov.h
"
30
#include "
pt-cbinop.h
"
31
#include "
pt-bp.h
"
32
#include "
pt-unop.h
"
33
#include "
pt-walk.h
"
34
35
// If a tree expression is a transpose or hermitian transpose, return
36
// the argument and corresponding operator.
37
38
static
octave_value::unary_op
39
strip_trans_herm
(
tree_expression
*&exp)
40
{
41
if
(exp->
is_unary_expression
())
42
{
43
tree_unary_expression
*uexp =
44
dynamic_cast<
tree_unary_expression
*
>
(exp);
45
46
octave_value::unary_op
op = uexp->
op_type
();
47
48
if
(op ==
octave_value::op_transpose
49
|| op ==
octave_value::op_hermitian
)
50
exp = uexp->
operand
();
51
else
52
op =
octave_value::unknown_unary_op
;
53
54
return
op;
55
}
56
else
57
return
octave_value::unknown_unary_op
;
58
}
59
60
static
octave_value::unary_op
61
strip_not
(
tree_expression
*&exp)
62
{
63
if
(exp->
is_unary_expression
())
64
{
65
tree_unary_expression
*uexp =
66
dynamic_cast<
tree_unary_expression
*
>
(exp);
67
68
octave_value::unary_op
op = uexp->
op_type
();
69
70
if
(op ==
octave_value::op_not
)
71
exp = uexp->
operand
();
72
else
73
op =
octave_value::unknown_unary_op
;
74
75
return
op;
76
}
77
else
78
return
octave_value::unknown_unary_op
;
79
}
80
81
// Possibly convert multiplication to trans_mul, mul_trans, herm_mul,
82
// or mul_herm.
83
84
static
octave_value::compound_binary_op
85
simplify_mul_op
(
tree_expression
*&a,
tree_expression
*&b)
86
{
87
octave_value::compound_binary_op
retop
88
=
octave_value::unknown_compound_binary_op
;
89
90
octave_value::unary_op
opa =
strip_trans_herm
(a);
91
92
if
(opa ==
octave_value::op_hermitian
)
93
retop =
octave_value::op_herm_mul
;
94
else
if
(opa ==
octave_value::op_transpose
)
95
retop =
octave_value::op_trans_mul
;
96
else
97
{
98
octave_value::unary_op
opb =
strip_trans_herm
(b);
99
100
if
(opb ==
octave_value::op_hermitian
)
101
retop =
octave_value::op_mul_herm
;
102
else
if
(opb ==
octave_value::op_transpose
)
103
retop =
octave_value::op_mul_trans
;
104
}
105
106
return
retop;
107
}
108
109
// Possibly convert left division to trans_ldiv or herm_ldiv.
110
111
static
octave_value::compound_binary_op
112
simplify_ldiv_op
(
tree_expression
*&a,
tree_expression
*&)
113
{
114
octave_value::compound_binary_op
retop
115
=
octave_value::unknown_compound_binary_op
;
116
117
octave_value::unary_op
opa =
strip_trans_herm
(a);
118
119
if
(opa ==
octave_value::op_hermitian
)
120
retop =
octave_value::op_herm_ldiv
;
121
else
if
(opa ==
octave_value::op_transpose
)
122
retop =
octave_value::op_trans_ldiv
;
123
124
return
retop;
125
}
126
127
// Possibly contract and/or with negation.
128
129
static
octave_value::compound_binary_op
130
simplify_and_or_op
(
tree_expression
*&a,
tree_expression
*&b,
131
octave_value::binary_op
op)
132
{
133
octave_value::compound_binary_op
retop
134
=
octave_value::unknown_compound_binary_op
;
135
136
octave_value::unary_op
opa =
strip_not
(a);
137
138
if
(opa ==
octave_value::op_not
)
139
{
140
if
(op ==
octave_value::op_el_and
)
141
retop =
octave_value::op_el_not_and
;
142
else
if
(op ==
octave_value::op_el_or
)
143
retop =
octave_value::op_el_not_or
;
144
}
145
else
146
{
147
octave_value::unary_op
opb =
strip_not
(b);
148
149
if
(opb ==
octave_value::op_not
)
150
{
151
if
(op ==
octave_value::op_el_and
)
152
retop =
octave_value::op_el_and_not
;
153
else
if
(op ==
octave_value::op_el_or
)
154
retop =
octave_value::op_el_or_not
;
155
}
156
}
157
158
return
retop;
159
}
160
161
tree_binary_expression
*
162
maybe_compound_binary_expression
(
tree_expression
*a,
tree_expression
*b,
163
int
l,
int
c,
octave_value::binary_op
t)
164
{
165
tree_expression
*ca = a, *cb = b;
166
octave_value::compound_binary_op
ct;
167
168
switch
(t)
169
{
170
case
octave_value::op_mul
:
171
ct =
simplify_mul_op
(ca, cb);
172
break
;
173
174
case
octave_value::op_ldiv
:
175
ct =
simplify_ldiv_op
(ca, cb);
176
break
;
177
178
case
octave_value::op_el_and
:
179
case
octave_value::op_el_or
:
180
ct =
simplify_and_or_op
(ca, cb, t);
181
break
;
182
183
default
:
184
ct =
octave_value::unknown_compound_binary_op
;
185
break
;
186
}
187
188
tree_binary_expression
*ret = (ct ==
octave_value::unknown_compound_binary_op
)
189
?
new
tree_binary_expression
(a, b, l, c, t)
190
:
new
tree_compound_binary_expression
(a, b, l,
191
c, t, ca,
192
cb, ct);
193
194
return
ret;
195
}
Generated on Mon Dec 30 2013 03:04:37 for GNU Octave by
1.8.1.2