| 116 | | // DEPRECATED |
|---|
| 117 | | /// As for exprSimplify, but allows the whole thing to be wrapped in parentheses. |
|---|
| 118 | | char [] subexprSimplify(char [] expr, char [] rank, char [] mulexpr, char [] indexexpr) |
|---|
| 119 | | { |
|---|
| 120 | | if (expr.length==1) { |
|---|
| 121 | | int r = subexprRank(expr, rank); |
|---|
| 122 | | char [] e = expr; |
|---|
| 123 | | if(indexexpr.length>0) { |
|---|
| 124 | | assert(r>0, "BLADE BUG: MISMATCHED INDEX " ~ expr ~ " " ~ indexexpr ~ " " ~ mulexpr); |
|---|
| 125 | | e = " {" ~ expr ~ indexexpr ~ "} "; |
|---|
| 126 | | } |
|---|
| 127 | | if (mulexpr.length>1) { |
|---|
| 128 | | // in this case, it's worth creating a new variable |
|---|
| 129 | | return "( {" ~ mulexpr ~ "} *" ~ e ~ ")"; |
|---|
| 130 | | } |
|---|
| 131 | | if (mulexpr.length>0) return "(" ~ mulexpr ~ "*" ~ e ~ ")"; |
|---|
| 132 | | return e; |
|---|
| 133 | | } |
|---|
| 134 | | // strip off the parentheses before simplifying |
|---|
| 135 | | return exprSimplify(expr[1..$-1], rank, mulexpr, indexexpr); |
|---|
| 136 | | } |
|---|
| 137 | | |
|---|
| 138 | | // DEPRECATED |
|---|
| 139 | | // Simplify a scalar*tensor expression. |
|---|
| 140 | | char [] simplifyScalarMul(char [] scalar, char [] tensor, char [] mulexpr, char [] rank, char [] indexexpr) |
|---|
| 141 | | { |
|---|
| 142 | | char [] m = scalar; |
|---|
| 143 | | if (mulexpr.length>0) m = "(" ~ mulexpr ~ "*" ~ scalar ~ ")"; |
|---|
| 144 | | // BUG: It's also worth scalar folding A*(B*U[]-V[]) into (A*B)*U[]+(-A)*V[], |
|---|
| 145 | | if (tensor.length > 1 && hasScalarMultiply(tensor[1..$-1], rank)) { |
|---|
| 146 | | // opportunity for scalar folding |
|---|
| 147 | | return subexprSimplify(tensor, rank, m, indexexpr); |
|---|
| 148 | | } else { |
|---|
| 149 | | if (m.length>1) m = " {" ~ m ~ "} "; |
|---|
| 150 | | return "(" ~ m ~ "*" ~ subexprSimplify(tensor, rank, "", indexexpr) ~ ")"; |
|---|
| 151 | | } |
|---|
| 152 | | } |
|---|
| 153 | | |
|---|
| 154 | | // DEPRECATED |
|---|
| 155 | | char [] getCommonMultiplucation(char [] expr, char [] rank) |
|---|
| 156 | | { |
|---|
| 157 | | if (expr.length>1 && expr[0]=='(') expr = expr[1..$-1]; |
|---|
| 158 | | else if (expr.length==1 && expr[0]>='A' && expr[0]<='Z'){ |
|---|
| 159 | | return rank[expr[0]-'A']=='0'? expr : ""; |
|---|
| 160 | | } else assert(0, "BLADE ICE: " ~ expr); |
|---|
| 161 | | if (expr.length>2 && (expr[0..2]=="++" || expr[0..2]=="--" || expr[$-2..$]=="++" || expr[$-2..$]=="--")) { |
|---|
| 162 | | return ""; |
|---|
| 163 | | } |
|---|
| 164 | | if (expr[0]=='+' || expr[0]=='-') return getCommonMultiplucation(expr[1..$], rank); |
|---|
| 165 | | int x = exprLength(expr); |
|---|
| 166 | | int y = x+1; |
|---|
| 167 | | assert(y < expr.length, "BLADE ICE:" ~ expr); |
|---|
| 168 | | // Deal with shifts, op=, and NCEG operators |
|---|
| 169 | | while (expr[y+1]=='<' || expr[y+1]=='>' || expr[y+1]=='=') ++y; |
|---|
| 170 | | char [] op = expr[x+1..y+1]; |
|---|
| 171 | | char [] left = expr[0..x+1]; |
|---|
| 172 | | char [] right = expr[y+1..$]; |
|---|
| 173 | | if (op=="[") { |
|---|
| 174 | | // (A)[C] can still have a multiply by scalar, if A contains a |
|---|
| 175 | | // multiply. |
|---|
| 176 | | if (left.length==1) return ""; |
|---|
| 177 | | return getCommonMultiplucation(left[1..$], rank); |
|---|
| 178 | | } |
|---|
| 179 | | if (op!="*") return ""; |
|---|
| 180 | | int leftrnk = subexprRank(left, rank); |
|---|
| 181 | | int rightrnk = subexprRank(right, rank); |
|---|
| 182 | | char [] leftMul = ""; |
|---|
| 183 | | char [] rightMul = ""; |
|---|
| 184 | | if (leftrnk == 0 && rightrnk == 0) { return expr; } |
|---|
| 185 | | if (leftrnk == 0) leftMul = left; else leftMul = getCommonMultiplucation(left, rank); |
|---|
| 186 | | if (rightrnk== 0) rightMul = right; else rightMul = getCommonMultiplucation(right, rank); |
|---|
| 187 | | if (leftMul!="" && rightMul!="") return "(" ~ leftMul ~ "*" ~ rightMul ~ ")"; |
|---|
| 188 | | if (leftMul!="") return leftMul; |
|---|
| 189 | | return rightMul; |
|---|
| 190 | | } |
|---|
| 191 | | |
|---|
| 192 | | // DEPRECATED |
|---|
| 193 | | // Simplify the expression, assuming global scalar multiply has already been removed. |
|---|
| 194 | | char [] simplifyWithoutMul(char [] rawExpr, char [] rank) |
|---|
| 195 | | { |
|---|
| 196 | | char [] expr = rawExpr; |
|---|
| 197 | | if (expr.length==1 && expr[0]>='A' && expr[0]<='Z') { |
|---|
| 198 | | return rank[expr[0]-'A']=='0'? "":expr; |
|---|
| 199 | | } else if (expr.length>1 && expr[0]=='(') expr = rawExpr[1..$-1]; |
|---|
| 200 | | |
|---|
| 201 | | if (expr.length>2 && (expr[0..2]=="++" || expr[0..2]=="--" || expr[$-2..$]=="++" || expr[$-2..$]=="--")) { |
|---|
| 202 | | return expr; |
|---|
| 203 | | } |
|---|
| 204 | | int x = exprLength(expr); |
|---|
| 205 | | int y = x+1; |
|---|
| 206 | | assert(y < expr.length, "BLADE ICE:" ~ expr); |
|---|
| 207 | | // Deal with shifts, op=, and NCEG operators |
|---|
| 208 | | while (expr[y+1]=='<' || expr[y+1]=='>' || expr[y+1]=='=') ++y; |
|---|
| 209 | | char [] op = expr[x+1..y+1]; |
|---|
| 210 | | char [] left = expr[0..x+1]; |
|---|
| 211 | | char [] right = expr[y+1..$]; |
|---|
| 212 | | /* |
|---|
| 213 | | if (op=="[") { |
|---|
| 214 | | // (A)[C] can still have a multiply by scalar, if A contains a |
|---|
| 215 | | // multiply. |
|---|
| 216 | | if (left.length==1) return left; |
|---|
| 217 | | return simplifyWithoutMul(left[1..$], rank); |
|---|
| 218 | | } |
|---|
| 219 | | */ |
|---|
| 220 | | if (op!="*") return subexprSimplify(rawExpr, rank, "", ""); |
|---|
| 221 | | |
|---|
| 222 | | int leftrnk = subexprRank(left, rank); |
|---|
| 223 | | int rightrnk = subexprRank(right, rank); |
|---|
| 224 | | char [] leftMul = ""; |
|---|
| 225 | | char [] rightMul = ""; |
|---|
| 226 | | if (leftrnk == 0 && rightrnk == 0) return ""; |
|---|
| 227 | | if (leftrnk == 0) leftMul = ""; else leftMul = simplifyWithoutMul(left, rank); |
|---|
| 228 | | if (rightrnk== 0) rightMul = ""; else rightMul = simplifyWithoutMul(right, rank); |
|---|
| 229 | | if (leftMul!="" && rightMul!="") return "(" ~ leftMul ~ "*" ~ rightMul ~ ")"; |
|---|
| 230 | | if (leftMul!="") return leftMul; |
|---|
| 231 | | return rightMul; |
|---|
| 232 | | } |
|---|
| 233 | | |
|---|
| 234 | | // DEPRECATED |
|---|
| 235 | | /** |
|---|
| 236 | | * Rewrite the expression, taking advantage of distributivity of [] and |
|---|
| 237 | | * associativity of *. Additionally, we group all scalars together, whenever |
|---|
| 238 | | * possible. |
|---|
| 239 | | * |
|---|
| 240 | | * This process creates compound scalars and vectors, delineated by " {" and "} ". |
|---|
| 241 | | * They will be removed in a subsequent step. |
|---|
| 242 | | */ |
|---|
| 243 | | char [] exprSimplify(char [] expr, char [] rank, char [] mulexpr, char [] indexexpr) |
|---|
| 244 | | { |
|---|
| 245 | | if (expr.length>3 && expr[0..2]=="d(") { // dot product |
|---|
| 246 | | assert(indexexpr=="", "BLADE ICE"); |
|---|
| 247 | | int x = exprLength(expr[2..$-1]); |
|---|
| 248 | | char [] left = expr[2..x+3]; |
|---|
| 249 | | char [] right = expr[x+4..$-1]; |
|---|
| 250 | | char [] leftmul = ""; |
|---|
| 251 | | char [] rightmul = ""; |
|---|
| 252 | | leftmul = getCommonMultiplucation(left, rank); |
|---|
| 253 | | rightmul = getCommonMultiplucation(right, rank); |
|---|
| 254 | | char [] m = leftmul; |
|---|
| 255 | | if (rightmul.length>0) m = m==""? rightmul : "(" ~ m ~ "*" ~rightmul~")"; |
|---|
| 256 | | if (mulexpr.length>0) m = m=="" ? mulexpr : "(" ~ m ~ "*" ~mulexpr~")"; |
|---|
| 257 | | if (m.length>1) m= "* {" ~ m ~ "} "; |
|---|
| 258 | | else if (m.length==1) m= "*" ~ m; |
|---|
| 259 | | assert(indexexpr.length==0, "BLADE ICE: rank mismatch in dot product"); |
|---|
| 260 | | return " {d(" ~ simplifyWithoutMul(left, rank) ~ "," ~ |
|---|
| 261 | | simplifyWithoutMul(right, rank) ~ ")} " ~ m; |
|---|
| 262 | | } |
|---|
| 263 | | // Deal with ++ and --. Only for scalars |
|---|
| 264 | | if (expr.length>2 && (expr[0..2]=="++" || expr[0..2]=="--")) { |
|---|
| 265 | | return expr[0..2] ~ subexprSimplify(expr[2..$], rank, mulexpr, indexexpr); |
|---|
| 266 | | } |
|---|
| 267 | | if (expr.length>2 && (expr[$-2..$]=="++" || expr[$-2..$]=="--")) { |
|---|
| 268 | | return subexprSimplify(expr[0..$-2], rank, mulexpr, indexexpr) ~ expr[$-2..$]; |
|---|
| 269 | | } |
|---|
| 270 | | // Deal with unary operators |
|---|
| 271 | | if (expr[0]=='-') { |
|---|
| 272 | | // Fold unary minus into a multiply, if possible. |
|---|
| 273 | | if (mulexpr.length>0) return subexprSimplify(expr[1..$], rank, "-" ~ mulexpr, indexexpr); |
|---|
| 274 | | return "-" ~ subexprSimplify(expr[1..$], rank, mulexpr, indexexpr); |
|---|
| 275 | | } |
|---|
| 276 | | // Just remove unary plus. |
|---|
| 277 | | if (expr[0]=='+') return subexprSimplify(expr[1..$], rank, mulexpr, indexexpr); |
|---|
| 278 | | |
|---|
| 279 | | int x = exprLength(expr); |
|---|
| 280 | | int y = x+1; |
|---|
| 281 | | assert(y < expr.length, expr); |
|---|
| 282 | | // Deal with shifts, op=, and NCEG operators |
|---|
| 283 | | while (expr[y+1]=='<' || expr[y+1]=='>' || expr[y+1]=='=') ++y; |
|---|
| 284 | | |
|---|
| 285 | | char [] op = expr[x+1..y+1]; |
|---|
| 286 | | char [] left = expr[0..x+1]; |
|---|
| 287 | | char [] right = expr[y+1..$]; |
|---|
| 288 | | if (expr[x+1]=='[') right = expr[y+1..$-1]; // drop off the ']'. |
|---|
| 289 | | if (op=="[") { |
|---|
| 290 | | // accumulate indexing and slicing operations |
|---|
| 291 | | return subexprSimplify(left, rank, mulexpr, "[" ~ right ~ "]" ~ indexexpr); |
|---|
| 292 | | } |
|---|
| 293 | | int lrank = subexprRank(left, rank); |
|---|
| 294 | | int rrank = subexprRank(right, rank); |
|---|
| 295 | | // Fold scalars together |
|---|
| 296 | | if (op=="*") { |
|---|
| 297 | | if (lrank==0) |
|---|
| 298 | | return simplifyScalarMul(left, right, mulexpr, rank, indexexpr); |
|---|
| 299 | | else if (rrank==0) |
|---|
| 300 | | return simplifyScalarMul(right, left, mulexpr, rank, indexexpr); |
|---|
| 301 | | // else it's matrix * matrix |
|---|
| 302 | | } |
|---|
| 303 | | if (op=="*=") { |
|---|
| 304 | | if (rrank==0) { |
|---|
| 305 | | char [] m = right; |
|---|
| 306 | | if (mulexpr.length>0) m ~= "*" ~ mulexpr; |
|---|
| 307 | | if (m.length>1) m= " {" ~ m ~ "} "; |
|---|
| 308 | | return "(" ~ subexprSimplify(left, rank, "", indexexpr)~ "*=" ~ m ~ ")"; |
|---|
| 309 | | } // else it's matrix *= matrix |
|---|
| 310 | | } |
|---|
| 311 | | return "(" ~ subexprSimplify(left, rank, mulexpr, indexexpr) ~ op ~ subexprSimplify(right, rank, mulexpr, indexexpr) ~ ")"; |
|---|
| 312 | | } |
|---|
| 313 | | |
|---|