xdiv.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1993-2012 John W. Eaton
00004 Copyright (C) 2008 Jaroslav Hajek
00005 Copyright (C) 2009-2010 VZLU Prague
00006 
00007 This file is part of Octave.
00008 
00009 Octave is free software; you can redistribute it and/or modify it
00010 under the terms of the GNU General Public License as published by the
00011 Free Software Foundation; either version 3 of the License, or (at your
00012 option) any later version.
00013 
00014 Octave is distributed in the hope that it will be useful, but WITHOUT
00015 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00016 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00017 for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with Octave; see the file COPYING.  If not, see
00021 <http://www.gnu.org/licenses/>.
00022 
00023 */
00024 
00025 #ifdef HAVE_CONFIG_H
00026 #include <config.h>
00027 #endif
00028 
00029 #include <cassert>
00030 
00031 #include "Array-util.h"
00032 #include "CMatrix.h"
00033 #include "dMatrix.h"
00034 #include "CNDArray.h"
00035 #include "dNDArray.h"
00036 #include "fCMatrix.h"
00037 #include "fMatrix.h"
00038 #include "fCNDArray.h"
00039 #include "fNDArray.h"
00040 #include "oct-cmplx.h"
00041 #include "dDiagMatrix.h"
00042 #include "fDiagMatrix.h"
00043 #include "CDiagMatrix.h"
00044 #include "fCDiagMatrix.h"
00045 #include "quit.h"
00046 
00047 #include "error.h"
00048 #include "xdiv.h"
00049 
00050 static inline bool
00051 result_ok (octave_idx_type info)
00052 {
00053   assert (info != -1);
00054 
00055   return (info != -2);
00056 }
00057 
00058 static void
00059 solve_singularity_warning (double rcond)
00060 {
00061   warning_with_id ("Octave:singular-matrix-div",
00062                    "matrix singular to machine precision, rcond = %g", rcond);
00063 }
00064 
00065 template <class T1, class T2>
00066 bool
00067 mx_leftdiv_conform (const T1& a, const T2& b, blas_trans_type blas_trans)
00068 {
00069   octave_idx_type a_nr = blas_trans == blas_no_trans ? a.rows () : a.cols ();
00070   octave_idx_type b_nr = b.rows ();
00071 
00072   if (a_nr != b_nr)
00073     {
00074       octave_idx_type a_nc = blas_trans == blas_no_trans ? a.cols () : a.rows ();
00075       octave_idx_type b_nc = b.cols ();
00076 
00077       gripe_nonconformant ("operator \\", a_nr, a_nc, b_nr, b_nc);
00078       return false;
00079     }
00080 
00081   return true;
00082 }
00083 
00084 #define INSTANTIATE_MX_LEFTDIV_CONFORM(T1, T2) \
00085   template bool mx_leftdiv_conform (const T1&, const T2&, blas_trans_type)
00086 
00087 INSTANTIATE_MX_LEFTDIV_CONFORM (Matrix, Matrix);
00088 INSTANTIATE_MX_LEFTDIV_CONFORM (Matrix, ComplexMatrix);
00089 INSTANTIATE_MX_LEFTDIV_CONFORM (ComplexMatrix, Matrix);
00090 INSTANTIATE_MX_LEFTDIV_CONFORM (ComplexMatrix, ComplexMatrix);
00091 
00092 template <class T1, class T2>
00093 bool
00094 mx_div_conform (const T1& a, const T2& b)
00095 {
00096   octave_idx_type a_nc = a.cols ();
00097   octave_idx_type b_nc = b.cols ();
00098 
00099   if (a_nc != b_nc)
00100     {
00101       octave_idx_type a_nr = a.rows ();
00102       octave_idx_type b_nr = b.rows ();
00103 
00104       gripe_nonconformant ("operator /", a_nr, a_nc, b_nr, b_nc);
00105       return false;
00106     }
00107 
00108   return true;
00109 }
00110 
00111 #define INSTANTIATE_MX_DIV_CONFORM(T1, T2) \
00112   template bool mx_div_conform (const T1&, const T2&)
00113 
00114 INSTANTIATE_MX_DIV_CONFORM (Matrix, Matrix);
00115 INSTANTIATE_MX_DIV_CONFORM (Matrix, ComplexMatrix);
00116 INSTANTIATE_MX_DIV_CONFORM (ComplexMatrix, Matrix);
00117 INSTANTIATE_MX_DIV_CONFORM (ComplexMatrix, ComplexMatrix);
00118 
00119 // Right division functions.
00120 //
00121 //       op2 / op1:   m   cm
00122 //            +--   +---+----+
00123 //   matrix         | 1 |  3 |
00124 //                  +---+----+
00125 //   complex_matrix | 2 |  4 |
00126 //                  +---+----+
00127 
00128 // -*- 1 -*-
00129 Matrix
00130 xdiv (const Matrix& a, const Matrix& b, MatrixType &typ)
00131 {
00132   if (! mx_div_conform (a, b))
00133     return Matrix ();
00134 
00135   octave_idx_type info;
00136   double rcond = 0.0;
00137 
00138   Matrix result
00139     = b.solve (typ, a.transpose (), info, rcond,
00140                solve_singularity_warning, true, blas_trans);
00141 
00142   return result.transpose ();
00143 }
00144 
00145 // -*- 2 -*-
00146 ComplexMatrix
00147 xdiv (const Matrix& a, const ComplexMatrix& b, MatrixType &typ)
00148 {
00149   if (! mx_div_conform (a, b))
00150     return ComplexMatrix ();
00151 
00152   octave_idx_type info;
00153   double rcond = 0.0;
00154 
00155   ComplexMatrix result
00156     = b.solve (typ, a.transpose (), info, rcond,
00157                solve_singularity_warning, true, blas_trans);
00158 
00159   return result.transpose ();
00160 }
00161 
00162 // -*- 3 -*-
00163 ComplexMatrix
00164 xdiv (const ComplexMatrix& a, const Matrix& b, MatrixType &typ)
00165 {
00166   if (! mx_div_conform (a, b))
00167     return ComplexMatrix ();
00168 
00169   octave_idx_type info;
00170   double rcond = 0.0;
00171 
00172   ComplexMatrix result
00173     = b.solve (typ, a.transpose (), info, rcond,
00174                solve_singularity_warning, true, blas_trans);
00175 
00176   return result.transpose ();
00177 }
00178 
00179 // -*- 4 -*-
00180 ComplexMatrix
00181 xdiv (const ComplexMatrix& a, const ComplexMatrix& b, MatrixType &typ)
00182 {
00183   if (! mx_div_conform (a, b))
00184     return ComplexMatrix ();
00185 
00186   octave_idx_type info;
00187   double rcond = 0.0;
00188 
00189   ComplexMatrix result
00190     = b.solve (typ, a.transpose (), info, rcond,
00191                solve_singularity_warning, true, blas_trans);
00192 
00193   return result.transpose ();
00194 }
00195 
00196 // Funny element by element division operations.
00197 //
00198 //       op2 \ op1:   s   cs
00199 //            +--   +---+----+
00200 //   matrix         | 1 |  3 |
00201 //                  +---+----+
00202 //   complex_matrix | 2 |  4 |
00203 //                  +---+----+
00204 
00205 Matrix
00206 x_el_div (double a, const Matrix& b)
00207 {
00208   octave_idx_type nr = b.rows ();
00209   octave_idx_type nc = b.columns ();
00210 
00211   Matrix result (nr, nc);
00212 
00213   for (octave_idx_type j = 0; j < nc; j++)
00214     for (octave_idx_type i = 0; i < nr; i++)
00215       {
00216         octave_quit ();
00217         result (i, j) = a / b (i, j);
00218       }
00219 
00220   return result;
00221 }
00222 
00223 ComplexMatrix
00224 x_el_div (double a, const ComplexMatrix& b)
00225 {
00226   octave_idx_type nr = b.rows ();
00227   octave_idx_type nc = b.columns ();
00228 
00229   ComplexMatrix result (nr, nc);
00230 
00231   for (octave_idx_type j = 0; j < nc; j++)
00232     for (octave_idx_type i = 0; i < nr; i++)
00233       {
00234         octave_quit ();
00235         result (i, j) = a / b (i, j);
00236       }
00237 
00238   return result;
00239 }
00240 
00241 ComplexMatrix
00242 x_el_div (const Complex a, const Matrix& b)
00243 {
00244   octave_idx_type nr = b.rows ();
00245   octave_idx_type nc = b.columns ();
00246 
00247   ComplexMatrix result (nr, nc);
00248 
00249   for (octave_idx_type j = 0; j < nc; j++)
00250     for (octave_idx_type i = 0; i < nr; i++)
00251       {
00252         octave_quit ();
00253         result (i, j) = a / b (i, j);
00254       }
00255 
00256   return result;
00257 }
00258 
00259 ComplexMatrix
00260 x_el_div (const Complex a, const ComplexMatrix& b)
00261 {
00262   octave_idx_type nr = b.rows ();
00263   octave_idx_type nc = b.columns ();
00264 
00265   ComplexMatrix result (nr, nc);
00266 
00267   for (octave_idx_type j = 0; j < nc; j++)
00268     for (octave_idx_type i = 0; i < nr; i++)
00269       {
00270         octave_quit ();
00271         result (i, j) = a / b (i, j);
00272       }
00273 
00274   return result;
00275 }
00276 
00277 // Funny element by element division operations.
00278 //
00279 //          op2 \ op1:   s   cs
00280 //               +--   +---+----+
00281 //   N-d array         | 1 |  3 |
00282 //                     +---+----+
00283 //   complex N-d array | 2 |  4 |
00284 //                     +---+----+
00285 
00286 NDArray
00287 x_el_div (double a, const NDArray& b)
00288 {
00289   NDArray result (b.dims ());
00290 
00291   for (octave_idx_type i = 0; i < b.length (); i++)
00292     {
00293       octave_quit ();
00294       result (i) = a / b (i);
00295     }
00296 
00297   return result;
00298 }
00299 
00300 ComplexNDArray
00301 x_el_div (double a, const ComplexNDArray& b)
00302 {
00303   ComplexNDArray result (b.dims ());
00304 
00305   for (octave_idx_type i = 0; i < b.length (); i++)
00306     {
00307       octave_quit ();
00308       result (i) = a / b (i);
00309     }
00310 
00311   return result;
00312 }
00313 
00314 ComplexNDArray
00315 x_el_div (const Complex a, const NDArray& b)
00316 {
00317   ComplexNDArray result (b.dims ());
00318 
00319   for (octave_idx_type i = 0; i < b.length (); i++)
00320     {
00321       octave_quit ();
00322       result (i) = a / b (i);
00323     }
00324 
00325   return result;
00326 }
00327 
00328 ComplexNDArray
00329 x_el_div (const Complex a, const ComplexNDArray& b)
00330 {
00331   ComplexNDArray result (b.dims ());
00332 
00333   for (octave_idx_type i = 0; i < b.length (); i++)
00334     {
00335       octave_quit ();
00336       result (i) = a / b (i);
00337     }
00338 
00339   return result;
00340 }
00341 
00342 // Left division functions.
00343 //
00344 //       op2 \ op1:   m   cm
00345 //            +--   +---+----+
00346 //   matrix         | 1 |  3 |
00347 //                  +---+----+
00348 //   complex_matrix | 2 |  4 |
00349 //                  +---+----+
00350 
00351 // -*- 1 -*-
00352 Matrix
00353 xleftdiv (const Matrix& a, const Matrix& b, MatrixType &typ, blas_trans_type transt)
00354 {
00355   if (! mx_leftdiv_conform (a, b, transt))
00356     return Matrix ();
00357 
00358   octave_idx_type info;
00359   double rcond = 0.0;
00360   return a.solve (typ, b, info, rcond, solve_singularity_warning, true, transt);
00361 }
00362 
00363 // -*- 2 -*-
00364 ComplexMatrix
00365 xleftdiv (const Matrix& a, const ComplexMatrix& b, MatrixType &typ, blas_trans_type transt)
00366 {
00367   if (! mx_leftdiv_conform (a, b, transt))
00368     return ComplexMatrix ();
00369 
00370   octave_idx_type info;
00371   double rcond = 0.0;
00372 
00373   return a.solve (typ, b, info, rcond, solve_singularity_warning, true, transt);
00374 }
00375 
00376 // -*- 3 -*-
00377 ComplexMatrix
00378 xleftdiv (const ComplexMatrix& a, const Matrix& b, MatrixType &typ, blas_trans_type transt)
00379 {
00380   if (! mx_leftdiv_conform (a, b, transt))
00381     return ComplexMatrix ();
00382 
00383   octave_idx_type info;
00384   double rcond = 0.0;
00385   return a.solve (typ, b, info, rcond, solve_singularity_warning, true, transt);
00386 }
00387 
00388 // -*- 4 -*-
00389 ComplexMatrix
00390 xleftdiv (const ComplexMatrix& a, const ComplexMatrix& b, MatrixType &typ, blas_trans_type transt)
00391 {
00392   if (! mx_leftdiv_conform (a, b, transt))
00393     return ComplexMatrix ();
00394 
00395   octave_idx_type info;
00396   double rcond = 0.0;
00397   return a.solve (typ, b, info, rcond, solve_singularity_warning, true, transt);
00398 }
00399 
00400 static void
00401 solve_singularity_warning (float rcond)
00402 {
00403   warning ("matrix singular to machine precision, rcond = %g", rcond);
00404   warning ("attempting to find minimum norm solution");
00405 }
00406 
00407 INSTANTIATE_MX_LEFTDIV_CONFORM (FloatMatrix, FloatMatrix);
00408 INSTANTIATE_MX_LEFTDIV_CONFORM (FloatMatrix, FloatComplexMatrix);
00409 INSTANTIATE_MX_LEFTDIV_CONFORM (FloatComplexMatrix, FloatMatrix);
00410 INSTANTIATE_MX_LEFTDIV_CONFORM (FloatComplexMatrix, FloatComplexMatrix);
00411 
00412 INSTANTIATE_MX_DIV_CONFORM (FloatMatrix, FloatMatrix);
00413 INSTANTIATE_MX_DIV_CONFORM (FloatMatrix, FloatComplexMatrix);
00414 INSTANTIATE_MX_DIV_CONFORM (FloatComplexMatrix, FloatMatrix);
00415 INSTANTIATE_MX_DIV_CONFORM (FloatComplexMatrix, FloatComplexMatrix);
00416 
00417 // Right division functions.
00418 //
00419 //       op2 / op1:   m   cm
00420 //            +--   +---+----+
00421 //   matrix         | 1 |  3 |
00422 //                  +---+----+
00423 //   complex_matrix | 2 |  4 |
00424 //                  +---+----+
00425 
00426 // -*- 1 -*-
00427 FloatMatrix
00428 xdiv (const FloatMatrix& a, const FloatMatrix& b, MatrixType &typ)
00429 {
00430   if (! mx_div_conform (a, b))
00431     return FloatMatrix ();
00432 
00433   octave_idx_type info;
00434   float rcond = 0.0;
00435 
00436   FloatMatrix result
00437     = b.solve (typ, a.transpose (), info, rcond,
00438                solve_singularity_warning, true, blas_trans);
00439 
00440   return result.transpose ();
00441 }
00442 
00443 // -*- 2 -*-
00444 FloatComplexMatrix
00445 xdiv (const FloatMatrix& a, const FloatComplexMatrix& b, MatrixType &typ)
00446 {
00447   if (! mx_div_conform (a, b))
00448     return FloatComplexMatrix ();
00449 
00450   octave_idx_type info;
00451   float rcond = 0.0;
00452 
00453   FloatComplexMatrix result
00454     = b.solve (typ, a.transpose (), info, rcond,
00455                solve_singularity_warning, true, blas_trans);
00456 
00457   return result.transpose ();
00458 }
00459 
00460 // -*- 3 -*-
00461 FloatComplexMatrix
00462 xdiv (const FloatComplexMatrix& a, const FloatMatrix& b, MatrixType &typ)
00463 {
00464   if (! mx_div_conform (a, b))
00465     return FloatComplexMatrix ();
00466 
00467   octave_idx_type info;
00468   float rcond = 0.0;
00469 
00470   FloatComplexMatrix result
00471     = b.solve (typ, a.transpose (), info, rcond,
00472                solve_singularity_warning, true, blas_trans);
00473 
00474   return result.transpose ();
00475 }
00476 
00477 // -*- 4 -*-
00478 FloatComplexMatrix
00479 xdiv (const FloatComplexMatrix& a, const FloatComplexMatrix& b, MatrixType &typ)
00480 {
00481   if (! mx_div_conform (a, b))
00482     return FloatComplexMatrix ();
00483 
00484   octave_idx_type info;
00485   float rcond = 0.0;
00486 
00487   FloatComplexMatrix result
00488     = b.solve (typ, a.transpose (), info, rcond,
00489                solve_singularity_warning, true, blas_trans);
00490 
00491   return result.transpose ();
00492 }
00493 
00494 // Funny element by element division operations.
00495 //
00496 //       op2 \ op1:   s   cs
00497 //            +--   +---+----+
00498 //   matrix         | 1 |  3 |
00499 //                  +---+----+
00500 //   complex_matrix | 2 |  4 |
00501 //                  +---+----+
00502 
00503 FloatMatrix
00504 x_el_div (float a, const FloatMatrix& b)
00505 {
00506   octave_idx_type nr = b.rows ();
00507   octave_idx_type nc = b.columns ();
00508 
00509   FloatMatrix result (nr, nc);
00510 
00511   for (octave_idx_type j = 0; j < nc; j++)
00512     for (octave_idx_type i = 0; i < nr; i++)
00513       {
00514         octave_quit ();
00515         result (i, j) = a / b (i, j);
00516       }
00517 
00518   return result;
00519 }
00520 
00521 FloatComplexMatrix
00522 x_el_div (float a, const FloatComplexMatrix& b)
00523 {
00524   octave_idx_type nr = b.rows ();
00525   octave_idx_type nc = b.columns ();
00526 
00527   FloatComplexMatrix result (nr, nc);
00528 
00529   for (octave_idx_type j = 0; j < nc; j++)
00530     for (octave_idx_type i = 0; i < nr; i++)
00531       {
00532         octave_quit ();
00533         result (i, j) = a / b (i, j);
00534       }
00535 
00536   return result;
00537 }
00538 
00539 FloatComplexMatrix
00540 x_el_div (const FloatComplex a, const FloatMatrix& b)
00541 {
00542   octave_idx_type nr = b.rows ();
00543   octave_idx_type nc = b.columns ();
00544 
00545   FloatComplexMatrix result (nr, nc);
00546 
00547   for (octave_idx_type j = 0; j < nc; j++)
00548     for (octave_idx_type i = 0; i < nr; i++)
00549       {
00550         octave_quit ();
00551         result (i, j) = a / b (i, j);
00552       }
00553 
00554   return result;
00555 }
00556 
00557 FloatComplexMatrix
00558 x_el_div (const FloatComplex a, const FloatComplexMatrix& b)
00559 {
00560   octave_idx_type nr = b.rows ();
00561   octave_idx_type nc = b.columns ();
00562 
00563   FloatComplexMatrix result (nr, nc);
00564 
00565   for (octave_idx_type j = 0; j < nc; j++)
00566     for (octave_idx_type i = 0; i < nr; i++)
00567       {
00568         octave_quit ();
00569         result (i, j) = a / b (i, j);
00570       }
00571 
00572   return result;
00573 }
00574 
00575 // Funny element by element division operations.
00576 //
00577 //          op2 \ op1:   s   cs
00578 //               +--   +---+----+
00579 //   N-d array         | 1 |  3 |
00580 //                     +---+----+
00581 //   complex N-d array | 2 |  4 |
00582 //                     +---+----+
00583 
00584 FloatNDArray
00585 x_el_div (float a, const FloatNDArray& b)
00586 {
00587   FloatNDArray result (b.dims ());
00588 
00589   for (octave_idx_type i = 0; i < b.length (); i++)
00590     {
00591       octave_quit ();
00592       result (i) = a / b (i);
00593     }
00594 
00595   return result;
00596 }
00597 
00598 FloatComplexNDArray
00599 x_el_div (float a, const FloatComplexNDArray& b)
00600 {
00601   FloatComplexNDArray result (b.dims ());
00602 
00603   for (octave_idx_type i = 0; i < b.length (); i++)
00604     {
00605       octave_quit ();
00606       result (i) = a / b (i);
00607     }
00608 
00609   return result;
00610 }
00611 
00612 FloatComplexNDArray
00613 x_el_div (const FloatComplex a, const FloatNDArray& b)
00614 {
00615   FloatComplexNDArray result (b.dims ());
00616 
00617   for (octave_idx_type i = 0; i < b.length (); i++)
00618     {
00619       octave_quit ();
00620       result (i) = a / b (i);
00621     }
00622 
00623   return result;
00624 }
00625 
00626 FloatComplexNDArray
00627 x_el_div (const FloatComplex a, const FloatComplexNDArray& b)
00628 {
00629   FloatComplexNDArray result (b.dims ());
00630 
00631   for (octave_idx_type i = 0; i < b.length (); i++)
00632     {
00633       octave_quit ();
00634       result (i) = a / b (i);
00635     }
00636 
00637   return result;
00638 }
00639 
00640 // Left division functions.
00641 //
00642 //       op2 \ op1:   m   cm
00643 //            +--   +---+----+
00644 //   matrix         | 1 |  3 |
00645 //                  +---+----+
00646 //   complex_matrix | 2 |  4 |
00647 //                  +---+----+
00648 
00649 // -*- 1 -*-
00650 FloatMatrix
00651 xleftdiv (const FloatMatrix& a, const FloatMatrix& b, MatrixType &typ, blas_trans_type transt)
00652 {
00653   if (! mx_leftdiv_conform (a, b, transt))
00654     return FloatMatrix ();
00655 
00656   octave_idx_type info;
00657   float rcond = 0.0;
00658   return a.solve (typ, b, info, rcond, solve_singularity_warning, true, transt);
00659 }
00660 
00661 // -*- 2 -*-
00662 FloatComplexMatrix
00663 xleftdiv (const FloatMatrix& a, const FloatComplexMatrix& b, MatrixType &typ, blas_trans_type transt)
00664 {
00665   if (! mx_leftdiv_conform (a, b, transt))
00666     return FloatComplexMatrix ();
00667 
00668   octave_idx_type info;
00669   float rcond = 0.0;
00670 
00671   return a.solve (typ, b, info, rcond, solve_singularity_warning, true, transt);
00672 }
00673 
00674 // -*- 3 -*-
00675 FloatComplexMatrix
00676 xleftdiv (const FloatComplexMatrix& a, const FloatMatrix& b, MatrixType &typ, blas_trans_type transt)
00677 {
00678   if (! mx_leftdiv_conform (a, b, transt))
00679     return FloatComplexMatrix ();
00680 
00681   octave_idx_type info;
00682   float rcond = 0.0;
00683   return a.solve (typ, b, info, rcond, solve_singularity_warning, true, transt);
00684 }
00685 
00686 // -*- 4 -*-
00687 FloatComplexMatrix
00688 xleftdiv (const FloatComplexMatrix& a, const FloatComplexMatrix& b, MatrixType &typ, blas_trans_type transt)
00689 {
00690   if (! mx_leftdiv_conform (a, b, transt))
00691     return FloatComplexMatrix ();
00692 
00693   octave_idx_type info;
00694   float rcond = 0.0;
00695   return a.solve (typ, b, info, rcond, solve_singularity_warning, true, transt);
00696 }
00697 
00698 // Diagonal matrix division.
00699 
00700 template <class MT, class DMT>
00701 MT
00702 mdm_div_impl (const MT& a, const DMT& d)
00703 {
00704   if (! mx_div_conform (a, d))
00705     return MT ();
00706 
00707   octave_idx_type m = a.rows (), n = d.rows (), l = d.length ();
00708   MT x (m, n);
00709   typedef typename DMT::element_type S;
00710   typedef typename MT::element_type T;
00711   const T *aa = a.data ();
00712   const S *dd = d.data ();
00713   T *xx = x.fortran_vec ();
00714 
00715   for (octave_idx_type j = 0; j < l; j++)
00716     {
00717       const S del = dd[j];
00718       if (del != S ())
00719         for (octave_idx_type i = 0; i < m; i++)
00720           xx[i] = aa[i] / del;
00721       else
00722         for (octave_idx_type i = 0; i < m; i++)
00723           xx[i] = T ();
00724       aa += m; xx += m;
00725     }
00726 
00727   for (octave_idx_type i = l*m; i < n*m; i++)
00728     xx[i] = T ();
00729 
00730   return x;
00731 }
00732 
00733 // Right division functions.
00734 //
00735 //       op2 / op1:   dm  cdm
00736 //            +--   +---+----+
00737 //   matrix         | 1 |    |
00738 //                  +---+----+
00739 //   complex_matrix | 2 |  3 |
00740 //                  +---+----+
00741 
00742 // -*- 1 -*-
00743 Matrix
00744 xdiv (const Matrix& a, const DiagMatrix& b)
00745 { return mdm_div_impl (a, b); }
00746 
00747 // -*- 2 -*-
00748 ComplexMatrix
00749 xdiv (const ComplexMatrix& a, const DiagMatrix& b)
00750 { return mdm_div_impl (a, b); }
00751 
00752 // -*- 3 -*-
00753 ComplexMatrix
00754 xdiv (const ComplexMatrix& a, const ComplexDiagMatrix& b)
00755 { return mdm_div_impl (a, b); }
00756 
00757 // Right division functions, float type.
00758 //
00759 //       op2 / op1:   dm  cdm
00760 //            +--   +---+----+
00761 //   matrix         | 1 |    |
00762 //                  +---+----+
00763 //   complex_matrix | 2 |  3 |
00764 //                  +---+----+
00765 
00766 // -*- 1 -*-
00767 FloatMatrix
00768 xdiv (const FloatMatrix& a, const FloatDiagMatrix& b)
00769 { return mdm_div_impl (a, b); }
00770 
00771 // -*- 2 -*-
00772 FloatComplexMatrix
00773 xdiv (const FloatComplexMatrix& a, const FloatDiagMatrix& b)
00774 { return mdm_div_impl (a, b); }
00775 
00776 // -*- 3 -*-
00777 FloatComplexMatrix
00778 xdiv (const FloatComplexMatrix& a, const FloatComplexDiagMatrix& b)
00779 { return mdm_div_impl (a, b); }
00780 
00781 template <class MT, class DMT>
00782 MT
00783 dmm_leftdiv_impl (const DMT& d, const MT& a)
00784 {
00785   if (! mx_leftdiv_conform (d, a, blas_no_trans))
00786     return MT ();
00787 
00788   octave_idx_type m = d.cols (), n = a.cols (), k = a.rows (), l = d.length ();
00789   MT x (m, n);
00790   typedef typename DMT::element_type S;
00791   typedef typename MT::element_type T;
00792   const T *aa = a.data ();
00793   const S *dd = d.data ();
00794   T *xx = x.fortran_vec ();
00795 
00796   for (octave_idx_type j = 0; j < n; j++)
00797     {
00798       for (octave_idx_type i = 0; i < l; i++)
00799         xx[i] = dd[i] != S () ? aa[i] / dd[i] : T ();
00800       for (octave_idx_type i = l; i < m; i++)
00801         xx[i] = T ();
00802       aa += k; xx += m;
00803     }
00804 
00805   return x;
00806 }
00807 
00808 // Left division functions.
00809 //
00810 //       op2 \ op1:         m   cm
00811 //                        +---+----+
00812 //   diag_matrix          | 1 |  2 |
00813 //                        +---+----+
00814 //   complex_diag_matrix  |   |  3 |
00815 //                        +---+----+
00816 
00817 // -*- 1 -*-
00818 Matrix
00819 xleftdiv (const DiagMatrix& a, const Matrix& b)
00820 { return dmm_leftdiv_impl (a, b); }
00821 
00822 // -*- 2 -*-
00823 ComplexMatrix
00824 xleftdiv (const DiagMatrix& a, const ComplexMatrix& b)
00825 { return dmm_leftdiv_impl (a, b); }
00826 
00827 // -*- 3 -*-
00828 ComplexMatrix
00829 xleftdiv (const ComplexDiagMatrix& a, const ComplexMatrix& b)
00830 { return dmm_leftdiv_impl (a, b); }
00831 
00832 // Left division functions, float type.
00833 //
00834 //       op2 \ op1:         m   cm
00835 //                        +---+----+
00836 //   diag_matrix          | 1 |  2 |
00837 //                        +---+----+
00838 //   complex_diag_matrix  |   |  3 |
00839 //                        +---+----+
00840 
00841 // -*- 1 -*-
00842 FloatMatrix
00843 xleftdiv (const FloatDiagMatrix& a, const FloatMatrix& b)
00844 { return dmm_leftdiv_impl (a, b); }
00845 
00846 // -*- 2 -*-
00847 FloatComplexMatrix
00848 xleftdiv (const FloatDiagMatrix& a, const FloatComplexMatrix& b)
00849 { return dmm_leftdiv_impl (a, b); }
00850 
00851 // -*- 3 -*-
00852 FloatComplexMatrix
00853 xleftdiv (const FloatComplexDiagMatrix& a, const FloatComplexMatrix& b)
00854 { return dmm_leftdiv_impl (a, b); }
00855 
00856 // Diagonal by diagonal matrix division.
00857 
00858 template <class MT, class DMT>
00859 MT
00860 dmdm_div_impl (const MT& a, const DMT& d)
00861 {
00862   if (! mx_div_conform (a, d))
00863     return MT ();
00864 
00865   octave_idx_type m = a.rows (), n = d.rows (), k = d.cols ();
00866   octave_idx_type l = std::min (m, n), lk = std::min (l, k);
00867   MT x (m, n);
00868   typedef typename DMT::element_type S;
00869   typedef typename MT::element_type T;
00870   const T *aa = a.data ();
00871   const S *dd = d.data ();
00872   T *xx = x.fortran_vec ();
00873 
00874   for (octave_idx_type i = 0; i < lk; i++)
00875     xx[i] = dd[i] != S () ? aa[i] / dd[i] : T ();
00876   for (octave_idx_type i = lk; i < l; i++)
00877     xx[i] = T ();
00878 
00879   return x;
00880 }
00881 
00882 // Right division functions.
00883 //
00884 //       op2 / op1:        dm  cdm
00885 //            +--        +---+----+
00886 //   diag_matrix         | 1 |    |
00887 //                       +---+----+
00888 //   complex_diag_matrix | 2 |  3 |
00889 //                       +---+----+
00890 
00891 // -*- 1 -*-
00892 DiagMatrix
00893 xdiv (const DiagMatrix& a, const DiagMatrix& b)
00894 { return dmdm_div_impl (a, b); }
00895 
00896 // -*- 2 -*-
00897 ComplexDiagMatrix
00898 xdiv (const ComplexDiagMatrix& a, const DiagMatrix& b)
00899 { return dmdm_div_impl (a, b); }
00900 
00901 // -*- 3 -*-
00902 ComplexDiagMatrix
00903 xdiv (const ComplexDiagMatrix& a, const ComplexDiagMatrix& b)
00904 { return dmdm_div_impl (a, b); }
00905 
00906 // Right division functions, float type.
00907 //
00908 //       op2 / op1:        dm  cdm
00909 //            +--        +---+----+
00910 //   diag_matrix         | 1 |    |
00911 //                       +---+----+
00912 //   complex_diag_matrix | 2 |  3 |
00913 //                       +---+----+
00914 
00915 // -*- 1 -*-
00916 FloatDiagMatrix
00917 xdiv (const FloatDiagMatrix& a, const FloatDiagMatrix& b)
00918 { return dmdm_div_impl (a, b); }
00919 
00920 // -*- 2 -*-
00921 FloatComplexDiagMatrix
00922 xdiv (const FloatComplexDiagMatrix& a, const FloatDiagMatrix& b)
00923 { return dmdm_div_impl (a, b); }
00924 
00925 // -*- 3 -*-
00926 FloatComplexDiagMatrix
00927 xdiv (const FloatComplexDiagMatrix& a, const FloatComplexDiagMatrix& b)
00928 { return dmdm_div_impl (a, b); }
00929 
00930 template <class MT, class DMT>
00931 MT
00932 dmdm_leftdiv_impl (const DMT& d, const MT& a)
00933 {
00934   if (! mx_leftdiv_conform (d, a, blas_no_trans))
00935     return MT ();
00936 
00937   octave_idx_type m = d.cols (), n = a.cols (), k = d.rows ();
00938   octave_idx_type l = std::min (m, n), lk = std::min (l, k);
00939   MT x (m, n);
00940   typedef typename DMT::element_type S;
00941   typedef typename MT::element_type T;
00942   const T *aa = a.data ();
00943   const S *dd = d.data ();
00944   T *xx = x.fortran_vec ();
00945 
00946   for (octave_idx_type i = 0; i < lk; i++)
00947     xx[i] = dd[i] != S () ? aa[i] / dd[i] : T ();
00948   for (octave_idx_type i = lk; i < l; i++)
00949     xx[i] = T ();
00950 
00951   return x;
00952 }
00953 
00954 // Left division functions.
00955 //
00956 //       op2 \ op1:         dm  cdm
00957 //                        +---+----+
00958 //   diag_matrix          | 1 |  2 |
00959 //                        +---+----+
00960 //   complex_diag_matrix  |   |  3 |
00961 //                        +---+----+
00962 
00963 // -*- 1 -*-
00964 DiagMatrix
00965 xleftdiv (const DiagMatrix& a, const DiagMatrix& b)
00966 { return dmdm_leftdiv_impl (a, b); }
00967 
00968 // -*- 2 -*-
00969 ComplexDiagMatrix
00970 xleftdiv (const DiagMatrix& a, const ComplexDiagMatrix& b)
00971 { return dmdm_leftdiv_impl (a, b); }
00972 
00973 // -*- 3 -*-
00974 ComplexDiagMatrix
00975 xleftdiv (const ComplexDiagMatrix& a, const ComplexDiagMatrix& b)
00976 { return dmdm_leftdiv_impl (a, b); }
00977 
00978 // Left division functions, float type.
00979 //
00980 //       op2 \ op1:         dm  cdm
00981 //                        +---+----+
00982 //   diag_matrix          | 1 |  2 |
00983 //                        +---+----+
00984 //   complex_diag_matrix  |   |  3 |
00985 //                        +---+----+
00986 
00987 // -*- 1 -*-
00988 FloatDiagMatrix
00989 xleftdiv (const FloatDiagMatrix& a, const FloatDiagMatrix& b)
00990 { return dmdm_leftdiv_impl (a, b); }
00991 
00992 // -*- 2 -*-
00993 FloatComplexDiagMatrix
00994 xleftdiv (const FloatDiagMatrix& a, const FloatComplexDiagMatrix& b)
00995 { return dmdm_leftdiv_impl (a, b); }
00996 
00997 // -*- 3 -*-
00998 FloatComplexDiagMatrix
00999 xleftdiv (const FloatComplexDiagMatrix& a, const FloatComplexDiagMatrix& b)
01000 { return dmdm_leftdiv_impl (a, b); }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines