SCM

SCM Repository

[matrix] Diff of /pkg/ChangeLog
ViewVC logotype

Diff of /pkg/ChangeLog

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1932, Fri Jun 29 16:43:47 2007 UTC revision 2120, Tue Mar 4 21:44:41 2008 UTC
# Line 1  Line 1 
1    2008-03-04  Martin Maechler  <maechler@stat.math.ethz.ch>
2    
3            * R/diagMatrix.R (subDiag): fix when x[..] became a vector
4    
5            * src/Tsparse.c (Tsparse_diagU2N): new utility, necessary for e.g.
6            * src/Csparse.c (Csparse_crossprod): use [CT]sparse_diagU2N() !!
7    
8            * R/Auxiliaries.R (.diagU2N): make use of new Tsparse_diagU2N
9    
10            * R/Ops.R ("-" (<sparseMatrix>)): use diagU2N()
11    
12            * src/chm_common.c (AS_CHM_FINISH): add note about problem
13            for triangular (diag = "U").
14    
15    2008-02-21  Martin Maechler  <maechler@stat.math.ethz.ch>
16    
17            * R/Auxiliaries.R (as_Csparse2): drop this, replacing by
18            * R/bind.R:  .Call(dense_to_Csparse, *)
19    
20    2008-02-20  Martin Maechler  <maechler@stat.math.ethz.ch>
21    
22            * R/Matrix.R (Matrix): no longer use coercions to specific classes
23                    (since we are discouraging them in user code).
24    
25            * tests/*.R: also replaces coercions to specific classes by
26            coercions to super classes.
27    
28            * R/denseMatrix.R (.dense2C): simplified by using forceSymmetric()
29    
30    
31    2008-02-19  Martin Maechler  <maechler@stat.math.ethz.ch>
32    
33            * man/CAex.Rd: example: coerce to symmetric*, not dsC*
34    
35            * src/dense.c (dense_band): generalized from ddense_band
36    
37            * R/ddenseMatrix.R (.trilDense,.triuDense, .bandDense):
38              now for "denseMatrix" (instead of just "ddense*"); much
39              simplified setMethod()s for these.
40    
41            * src/dense.c (dense_to_symmetric): generalized from ddense_*
42    
43    2008-02-18  Martin Maechler  <maechler@stat.math.ethz.ch>
44    
45            * R/AllGeneric.R: forceSymmetric() generic: fast no-checking
46            version of as(*, "symmetricMatric").
47    
48            * src/dense.c (ddense_to_symmetric): add 'symm_test' argument, and
49            * R/symmetricMatrix.R: set it TRUE in coercion to "symmetricMatrix"
50    
51    2008-02-16  Martin Maechler  <maechler@stat.math.ethz.ch>
52    
53            * R/Matrix.R (subset.ij): utility, as first step to faster
54               M [ <ij-matrix> ] indexing.
55    
56            * R/Matrix.R (.M.sub.i.logical): M[ <logical> ] : try better.
57    
58            * src/dense.c (ddense_symmpart, ddense_skewpart): new functions
59            for more efficient symmpart() and skewpart() methods.
60    
61            * src/Mutils.c (equal_string_vectors): utility
62    
63            * src/dense.c (ddense_to_symmetric): new function used in
64    
65            * R/symmetricMatrix.R: setAs(., "symmetricMatrix")
66    
67            * R/sparseMatrix.R, et_al (isSymmetric): add '...' to formals, in
68            order to match the generic (and evade .local(..)).
69    
70            * R/dsCMatrix.R: dgC -> dsC: use C code!
71    
72            * NAMESPACE, R/AllGeneric.R (symmpart, skewpart): new functions
73            as per TODO
74    
75            * R/Auxiliaries.R (setZero, all0Matrix): new utilities
76    
77            * R/symmetricMatrix.R: obvious symmpart(), skewpart() methods
78    
79    
80    2008-02-15  Martin Maechler  <maechler@stat.math.ethz.ch>
81    
82            * R/Ops.R (.Arith.Csparse): use diagU2N when needed in triangular
83    
84            * R/Auxiliaries.R (non0.i): take out of non0ind
85    
86            * R/ddenseMatrix.R (.trilDense, .triuDense, .bandDense):
87            make tril(), triu(), band() work for "matrix" and all "dense*"
88    
89            * R/triangularMatrix.R (.tri[lu].tr): need .diagU2N(*)
90            * tests/simple.R: test the fix above
91    
92            * R/sparseMatrix.R ([): simplification: no coerce to <general>
93                    before we use as(., <Tsparse>)[...] anyway
94    
95            * R/Rsparse.R (.viaC.to.R): mostly instead of .viaC.to.dgR()
96    
97            * R/triangularMatrix.R (isTriangular): methods for all subclasses
98            instead of "triangularMatrix" -- just to disambiguate
99    
100    2008-02-14  Martin Maechler  <maechler@stat.math.ethz.ch>
101    
102            * tests/Class+Meth.R (dotestMat): add m[FALSE, FALSE] { <-> TODO}
103            * tests/indexing.R: example that fails above
104    
105    2008-01-26  Martin Maechler  <maechler@stat.math.ethz.ch>
106    
107            * R/Matrix.R (.M.sub.i.2col): fix for logical matrix indexing
108            * R/Tsparse.R (.TM.sub.i.2col, .TM.repl.i.2col): ditto;
109                    now, M[lower.tri(M)] and  M[lower.tri(M)] <- v  work better
110    
111            * src/Tsparse.c (Tsparse_to_tCsparse): new fast utility.
112            * src/Tsparse.h, init.c: ditto
113            * R/Auxiliaries.R (isTriT): new; faster than going via Csparse
114                 both isTriC() and isTriT() now return TRUE with "kind" or FALSE.
115            * R/sparseMatrix.R (isTriangular): hence simplified
116    
117    2008-01-24  Martin Maechler  <maechler@stat.math.ethz.ch>
118    
119            * R/Ops.R (.Arith.Csparse): new utility factored out of former
120              <dgC> o <dgC>, extended for triangular and also used in  <dtC> o <dtC>.
121    
122    2008-01-23  Martin Maechler  <maechler@stat.math.ethz.ch>
123    
124            * tests/factorizing.R (checkSchur): and more tests for checking Schur()
125    
126            * inst/test-tools.R (isOrthogonal): new function; also file restructured
127    
128    2008-01-22  Martin Maechler  <maechler@stat.math.ethz.ch>
129    
130            * R/ngTMatrix.R: allow as(<numeric matrix>, "ngTMatrix") and hence
131            coercion to "nMatrix" and "pMatrix"
132    
133            * R/AllClass.R: "Schur" class;  "number" class union
134            * man/number-class.Rd:
135            * man/Schur-class.Rd:
136    
137            * R/eigen.R (.dgeSchur): utility, and return "Schur" class
138            (.simpleSchur): Schur() method for diagonal matrices
139            (.triSchur):    Schur() method for triangular matrices
140            (Schur.sym):    Schur() for symmetric matrices {building on eigen()}.
141    
142    
143    2008-01-21  Martin Maechler  <maechler@stat.math.ethz.ch>
144    
145            * src/dgCMatrix.c (dgCMatrix_QR): set @Dim slot (as per doc)
146    
147    2008-01-15  Martin Maechler  <maechler@stat.math.ethz.ch>
148    
149            * R/CHMfactor.R (solve): method for b="numeric", but also b="ANY"
150                    in order to ensure 'system = *' is not lost;
151                    formals()$system instead of cut&paste.
152            * tests/factorizing.R: test solve(<CHM..>, <numeric>)
153    
154    2008-01-11  Martin Maechler  <maechler@stat.math.ethz.ch>
155    
156            * DESCRIPTION (Date): make ready for release --> 0.999375-4
157    
158            * R/dgeMatrix.R: fix rcond() method for "dgeMatrix".
159    
160    2007-12-08  Martin Maechler  <maechler@stat.math.ethz.ch>
161    
162            * R/pMatrix.R: as(*, "matrix") now returns 0/1 *integer* matrix,
163                    and hence does as.vector(.).
164            * man/pMatrix-class.Rd: docs
165            * R/sparseMatrix.R: fix for printing "integer sparse"
166    
167            * tests/Class+Meth.R (tstMatrixClass): test M[FALSE], M[2] etc
168    
169            * R/Matrix.R and others: use "exact" function argument list for
170                    both "["   : (x, i,j, ..., drop)
171                    and  "[<-" : (x, i,j, ..., value)
172    
173            * R/denseMatrix.R: M[i] and M[i] <- v  (i vector) now work
174            * R/Tsparse.R (replTmat):    ditto
175            * R/diagMatrix.R (replDiag): ditto
176            * R/Csparse.R (replCmat):    ditto {was it worth the pain?}
177            * tests/indexing.R: testing the above
178    
179    2007-12-07  Martin Maechler  <maechler@stat.math.ethz.ch>
180    
181            * R/sparseMatrix.R (cov2cor): method for sparse matrices
182    
183            * R/diagMatrix.R ([<-): fix   D[ cbind(i,j) ] <- v
184    
185            * R/bind2.R: fix for Rsparse* and rbind2(dense,dense)
186    
187            * tests/Class+Meth.R: test cbind2, rbind2  and  diag<-
188    
189    2007-12-06  Martin Maechler  <maechler@stat.math.ethz.ch>
190    
191            * R/Matrix.R: "generic" cov2cor() method
192    
193            * R/nearPD.R: new 'only.values', 'keepDiag' arguments;
194                    speed up Q %*% D %*% t(Q)
195            * tests/dpoMatrix.R: test nearPD()
196    
197    2007-12-05  Doug Bates and Martin Maechler
198    
199            * R/sparseMatrix.R: xtabs(*, sparse=.) function; an extention of
200            stats::xtabs() allowing to create sparse matrices.
201    
202    2007-10-08  Martin Maechler  <maechler@stat.math.ethz.ch>
203    
204            * DESCRIPTION (Version): *-4 (released *-3 two days ago)
205    
206    2007-10-06  Martin Maechler  <maechler@stat.math.ethz.ch>
207    
208            * R/pMatrix.R: solve(<Matrix>, <pMatrix>)
209    
210    2007-10-05  Martin Maechler  <maechler@stat.math.ethz.ch>
211    
212            * R/LU.R: solve() method for "denseLU"
213    
214    2007-10-01  Martin Maechler  <maechler@stat.math.ethz.ch>
215    
216            * DESCRIPTION (Version): 0.999375-3 preparing for release
217    
218            * R/AllGeneric.R: simplify  if(.) .. else .. for R <= 2.5.1
219    
220            * R/Matrix.R (Matrix): .Internal(matrix(..)) different for R >= 2.7.0
221    
222    2007-09-26  Martin Maechler  <maechler@stat.math.ethz.ch>
223    
224            * R/pMatrix.R (.m.mult.pMat): fix <matrix> %*% <pMatrix>,
225              thanks to Kasper Kristensen.
226            * tests/matprod.R: regression test for that.
227    
228    2007-09-23 17:32  Douglas Bates <bates@stat.wisc.edu>
229    
230            * [r4778] R/AllGeneric.R: Check R version before defining generics for
231              primitives
232    
233    2007-09-13  Martin Maechler  <maechler@stat.math.ethz.ch>
234    
235            * R/denseMatrix.R (rcond): method
236            * R/sparseQR.R (rcond): method, use x or t(x)
237    
238    2007-09-12  Martin Maechler  <maechler@stat.math.ethz.ch>
239    
240            * R/dgeMatrix.R (rcond): method: work via qr.R() for non-square
241            matrices.
242            * R/sparseMatrix.R: Ditto for all other rcond() method definitions.
243    
244            * man/rcond.Rd: mention the more general definition, and add
245            example for non-square matrices.
246    
247            * man/chol.Rd: new file, for the S4 chol() generic and all methods.
248    
249    2007-09-11  Martin Maechler  <maechler@stat.math.ethz.ch>
250    
251            * R/sparseQR.R: add qr.R() method [to be used for rcond()]
252    
253    2007-09-01  Martin Maechler  <maechler@stat.math.ethz.ch>
254    
255            * R/Matrix.R ([<-): add (Matrix,missing,ANY,Matrix) etc
256            * tests/indexing.R: add new regression for the above cases.
257    
258    2007-08-30  Martin Maechler  <maechler@stat.math.ethz.ch>
259    
260            * src/Mutils.h (__sun): clause for alloca.h on Solaris
261    
262    2007-08-16  Martin Maechler  <maechler@stat.math.ethz.ch>
263    
264            * DESCRIPTION (Date, Version): 0.999375-2
265    
266    2007-08-15  Martin Maechler  <maechler@stat.math.ethz.ch>
267    
268            * R/HBMM.R (readMM): make work for pattern matrices as well
269    
270    2007-08-14 13:07  Douglas Bates <bates@stat.wisc.edu>
271    
272            * [r4730] src/Mutils.h: declare alloca
273            * [r4734] NAMESPACE, R/AllGeneric.R, R/Csparse.R, R/HBMM.R, R/Tsparse.R,
274              R/dgCMatrix.R, R/dgTMatrix.R, R/dsCMatrix.R, R/dsTMatrix.R,
275              man/externalFormats.Rd, src/Csparse.c, src/Csparse.h, src/DEPS.mkf,
276              src/HBMM.c, src/HBMM.h, src/Mutils.h, src/SOURCES_C.mkf, src/init.c,
277              src/mmio.c, src/mmio.h: Remove deprecated function writeHB and its
278              methods; switch writeMM to use CHOLMOD code; repair readMM
279    
280    2007-08-14  Martin Maechler  <maechler@stat.math.ethz.ch>
281    
282            * R/nearPD.R, man/nearPD.Rd (nearPD): new function built on Jens
283            Oehlschlaegel's ... result type still to be discussed!
284    
285    2007-08-10  Martin Maechler  <maechler@stat.math.ethz.ch>
286    
287            * man/image-methods.Rd: new, combining all image() methods
288    
289    2007-08-09  Martin Maechler  <maechler@stat.math.ethz.ch>
290    
291            * R/dgCMatrix.R: define qr() and lu() methods for "sparseMatrix"
292            to work via dgC...
293    
294            * R/Matrix.R (Matrix): special treatment for "table" (S3)
295    
296    2007-08-07  Martin Maechler  <maechler@stat.math.ethz.ch>
297    
298            * R/dgTMatrix.R (image): change defaults to
299                    aspect = "iso", colorkey = FALSE
300    
301    2007-08-06  Martin Maechler  <maechler@stat.math.ethz.ch>
302    
303            * src/dsyMatrix.c (dsyMatrix_matrix_mm): 'b' might be matrix;
304            must copy its *expanded* x slot before LAPACK call.
305    
306            * tests/matprod.R: test the last days' changes.
307    
308    2007-08-06 16:43  Douglas Bates <bates@stat.wisc.edu>
309    
310            * [r4712] inst/include/Matrix_stubs.c: Change R_cholmod_printf in stubs
311              as well as in sources
312            * [r4713] src/dsyMatrix.c: Duplicate the contents of the RHS before
313              Lapack call
314    
315    2007-08-03  Martin Maechler  <maechler@stat.math.ethz.ch>
316    
317            * R/Matrix.R (%*%, crossprod, tcrossprod): add method for
318                    ("Matrix", "matrix") which is needed in some cases.
319            Ditto for solve().
320    
321            * R/colSums.R (.as.dge.Fun): need ddenseMatrix methods to avoid
322            infinite recursion in dispatch for some cases.
323    
324    2007-08-02 08:48  Martin Maechler <maechler@stat.math.ethz.ch>
325    
326            * [r4693] src/chm_common.c: R_cholmod_printf() instead of Rprintf() just
327              so pointers match
328    
329    2007-08-02  Martin Maechler  <maechler@stat.math.ethz.ch>
330    
331            * DESCRIPTION (Date): set ready for release -- 0.999375-1
332    
333    2007-08-01 15:44  Douglas Bates <bates@stat.wisc.edu>
334    
335            * [r4686] inst/include/Matrix.h, inst/include/Matrix_stubs.c,
336              src/chm_common.c, src/chm_common.h: Change API for
337              numeric_as_chm_dense and N_AS_CHM_DN
338    
339    2007-08-01  Martin Maechler  <maechler@stat.math.ethz.ch>
340    
341            * src/dtrMatrix.c (dtrMatrix_matrix_mm): fix dimensionality check (!)
342            * tests/matprod.R: regr.test for it
343    
344    2007-07-20  Martin Maechler  <maechler@stat.math.ethz.ch>
345    
346            * R/dMatrix.R: fix from Brian for   Math2(., digits = "missing")
347            * tests/group-methods.R: and regression-test it
348    
349    2007-07-19 19:45  Douglas Bates <bates@stat.wisc.edu>
350    
351            * [r4642] inst/include/Matrix.h, inst/include/Matrix_stubs.c,
352              inst/include/cholmod.h, src/chm_common.c, src/init.c: Export
353              triplet_to_sparse, documentation, use typedefs
354    
355    2007-07-18  Martin Maechler  <maechler@stat.math.ethz.ch>
356    
357            * man/dpoMatrix-class.Rd: added 'corMatrix' example
358    
359            * src/dsyMatrix.[ch] (dsyMatrix_as_matrix): new 'keep_dimnames' arg
360            * src/dtrMatrix.[ch] (dtrMatrix_as_matrix): ditto
361            * src/init.c, R/dsyMatrix.R, R/dtrMatrix.R, R/lgTMatrix.R: ditto
362    
363            * R/lsparseMatrix.R: bug fix in "all" method
364            * R/Ops.R (.do.Logic.lsparse): "|" bug in borderline case
365    
366            * R/dsyMatrix.R (coerce->dsTMatrix): (i,j) slots should *not* have names
367            * R/ngTMatrix.R (coerce->ngTMatrix): ditto;
368                    + matrix |-> nMatrix coercion
369            * R/pMatrix.R: + setAs()  to dMatrix and from nMatrix
370            * man/pMatrix-class.Rd: ditto
371    
372            * R/Matrix.R (Summary): method for non-dMatrix
373    
374            * tests/Class+Meth.R (extraValid): new check about "dirty" slots
375            * tests/Class+Meth.R (tstMatrixClass): test norm(.);
376                    test all Summary methods.
377    
378    2007-07-16  Martin Maechler  <maechler@stat.math.ethz.ch>
379    
380            * R/dgeMatrix.R (norm, rcond): methods for 'matrix'
381    
382    2007-07-14  Martin Maechler  <maechler@stat.math.ethz.ch>
383    
384            * R/sparseMatrix.R (norm): simple methods for sparseMatrix
385    
386            * R/pMatrix.R (t?crossprod): methods for pMatrix
387    
388    2007-07-10  Douglas Bates  <bates@stat.wisc.edu>
389    
390            * src/dgeMatrix.c (dgeMatrix_colsums): Get the logic straight.
391    
392    2007-07-09 20:45  Douglas Bates <bates@stat.wisc.edu>
393    
394            * [r4579] src/dgeMatrix.c: Untangle horrible code in dgeMatrix_colsums
395              trying to fix a subtle bug - which has been somewhere else.
396    
397    2007-07-09 19:43  Martin Maechler <maechler@stat.math.ethz.ch>
398    
399            * [r4578] src/dgeMatrix.c: "cleaned" dgeMatrix_colsums() - but did not
400              solve the bug
401    
402    2007-07-08  Martin Maechler  <maechler@stat.math.ethz.ch>
403    
404            * src/dgCMatrix.c (compressed_to_TMatrix):
405    
406    2007-07-07  Martin Maechler  <maechler@stat.math.ethz.ch>
407    
408            * src/Csparse.c (Rsparse_validate): new, to have some validity
409            checking for RsparseMatrix
410            * src/dgCMatrix.c (xRMatrix_validate): ditto
411            * src/dtCMatrix.c (tRMatrix_validate): ditto
412    
413    2007-07-07  Douglas Bates <bates@stat.wisc.edu>
414    
415            * [r4567] R/AllClass.R: Slots already in RsparseMatrix were redefined in
416              lgRMatrix
417            * [r4568] DESCRIPTION: Prepare for bug-fix release
418            * [r4570] src/CHOLMOD/Check/cholmod_write.c: Include cholmod_matrixops.h
419              for declaration of cholmod_symmetry
420    
421    2007-07-06  Martin Maechler  <maechler@stat.math.ethz.ch>
422    
423            * DESCRIPTION (Version): 0.999375 merged into the trunk; ready for
424            release.
425    
426    2007-07-06 14:11  Douglas Bates <bates@stat.wisc.edu>
427    
428            * [r4559] src/iohb.c, src/iohb.h: Remove Harwell-Boeing input/output
429              functions - no longer used
430            * [r4560] src/HBMM.c, src/Mutils.c, src/dgTMatrix.c, src/dgeMatrix.c,
431              src/dspMatrix.c, src/dsyMatrix.c, src/dtCMatrix.c,
432              src/factorizations.c, src/sparseQR.c: Replace most calls to Calloc by
433              Alloca
434    
435    2007-07-06 13:14  Martin Maechler <maechler@stat.math.ethz.ch>
436    
437            * [r4558] inst/doc/Comparisons.Rnw, src/CHMfactor.c, src/Csparse.c,
438              src/Tsparse.c, src/chm_common.c, src/chm_common.h, src/dense.c,
439              src/dgCMatrix.c, src/dsCMatrix.c, src/dtTMatrix.c, src/sparseQR.c,
440              src/t_gCMatrix_colSums.c: more R_CheckStack()s
441    
442    2007-07-05 18:12  Douglas Bates <bates@stat.wisc.edu>
443    
444            * [r4550] inst/include/Matrix.h: Add the macro N_AS_CHM_DN to "alloca"
445              the required amount of memory then call M_numeric_as_chm_dense.
446            * [r4556] src/Mutils.h, src/dgCMatrix.c: Define and use the Alloca macro
447              (like Calloc but calling alloca)
448    
449    2007-07-05  Martin Maechler  <maechler@stat.math.ethz.ch>
450    
451            * R/sparseMatrix.R (printSpMatrix): renamed from prSpMatrix()
452            and extended with more sophisticated 'col.names' option.
453            * NAMESPACE: export  printSparseMatrix()
454            * man/printSpMatrix.Rd: document, incl. examples
455    
456    2007-07-04 16:21  Douglas Bates <bates@stat.wisc.edu>
457    
458            * [r4543] src/cs_utils.c, src/cs_utils.h, src/dgCMatrix.c,
459              src/dtCMatrix.c, src/sparseQR.c: CSP typedef for *cs and macro
460              AS_CSP. API change - pass the empty structure to Matrix_as_cs.
461    
462    2007-07-04  Martin Maechler  <maechler@stat.math.ethz.ch>
463    
464            * DESCRIPTION (Version): 0.99875-4
465    
466            * tests/Class+Meth.R (tstMatrixClass): add dimnames, and hence test
467            some dimnames perservation.
468    
469            * R/dsTMatrix.R (t-method): keep dimnames
470            * R/dtTMatrix.R:  ditto
471    
472            * R/sparseMatrix.R (prSpMatrix): print colnames when non-trivial
473            and ncol(.) < 10
474    
475            * src/cs_utils.c: drop check_class() and use Matrix_check_class()
476            from Mutils.h
477    
478            * src/lgCMatrix.c ([ln]csc_to_matrix): no longer lose dimnames,
479            e.g. in as(<ngCMatrix>, "matrix")
480    
481    2007-07-01 13:27  Douglas Bates <bates@stat.wisc.edu>
482    
483            * [r4529] .: Create a branch for the API changes from the 0.99875
484              series to the 0.999375 series
485            * [r4530] DESCRIPTION, inst/include/Matrix.h,
486              inst/include/Matrix_stubs.c, src/CHMfactor.c, src/Csparse.c,
487              src/Mutils.h, src/Tsparse.c, src/chm_common.c, src/chm_common.h,
488              src/dense.c, src/dgCMatrix.c, src/dsCMatrix.c, src/dtTMatrix.c,
489              src/t_gCMatrix_colSums.c: API change - pass the empty structure to the
490              as_cholmod_x functions
491    
492    2007-06-30 09:05  Martin Maechler <maechler@stat.math.ethz.ch>
493    
494            * [r4527] trunk/Matrix/DESCRIPTION, trunk/Matrix/NAMESPACE,
495              trunk/Matrix/inst/doc/Comparisons.Rnw: add session- and hardware-info
496              to Comparisons
497    
498    >>>>>>> .merge-right.r4561
499  2007-06-29  Martin Maechler  <maechler@stat.math.ethz.ch>  2007-06-29  Martin Maechler  <maechler@stat.math.ethz.ch>
500    
501          * DESCRIPTION (Version): 0.99875-3 ready to be released.          * DESCRIPTION (Version): 0.99875-3 ready to be released.

Legend:
Removed from v.1932  
changed lines
  Added in v.2120

root@r-forge.r-project.org
ViewVC Help
Powered by ViewVC 1.0.0  
Thanks to:
Vienna University of Economics and Business Powered By FusionForge