Hoyt's FORK of DemoIccMAX 2.1.17.hoyt
Documentation for Hoyt's FORK of DemoIccMAX
Loading...
Searching...
No Matches
IccSolve.cpp
Go to the documentation of this file.
1/** @file
2 File: IccSolve.cpp
3
4 Contains: Implementation of Matrix Solver
5
6 Version: V1
7
8 Copyright: (c) see ICC Software License
9*/
10
11/*
12 * The ICC Software License, Version 0.1
13 *
14 *
15 * Copyright (c) 2003-2006 The International Color Consortium. All rights
16 * reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 *
22 * 1. Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 *
25 * 2. Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in
27 * the documentation and/or other materials provided with the
28 * distribution.
29 *
30 * 3. In the absence of prior written permission, the names "ICC" and "The
31 * International Color Consortium" must not be used to imply that the
32 * ICC organization endorses or promotes products derived from this
33 * software.
34 *
35 *
36 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39 * DISCLAIMED. IN NO EVENT SHALL THE INTERNATIONAL COLOR CONSORTIUM OR
40 * ITS CONTRIBUTING MEMBERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This software consists of voluntary contributions made by many
51 * individuals on behalf of the The International Color Consortium.
52 *
53 *
54 * Membership in the ICC is encouraged when this software is used for
55 * commercial purposes.
56 *
57 *
58 * For more information on The International Color Consortium, please
59 * see <http://www.color.org/>.
60 *
61 *
62 */
63
64//////////////////////////////////////////////////////////////////////
65// HISTORY:
66//
67// -Initial implementation by Max Derhak 4-12-2016
68//
69//////////////////////////////////////////////////////////////////////
70
71#include "IccSolve.h"
72#include "IccUtil.h"
73#include <cstring>
74
75#ifdef ICC_USE_EIGEN_SOLVER
76#include<Eigen/Core>
77#include<Eigen/SVD>
78
79template<typename _Matrix_Type_, typename _Vector_Type_>
80_Vector_Type_ solve(const _Matrix_Type_ &a, const _Vector_Type_ y, icFloatNumber epsilon = std::numeric_limits<icFloatNumber>::epsilon())
81{
82 Eigen::JacobiSVD< _Matrix_Type_ > svd(a ,Eigen::ComputeThinU | Eigen::ComputeThinV);
83 icFloatNumber tolerance = epsilon * std::max(a.cols(), a.rows()) *svd.singularValues().array().abs()(0);
84 return svd.matrixV() * (svd.singularValues().array().abs() > tolerance).select(svd.singularValues().array().inverse(), 0).matrix().asDiagonal() * svd.matrixU().adjoint() * y;
85}
86
87
88typedef Eigen::Matrix<icFloatNumber, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> MatrixXn;
89typedef Eigen::Matrix<icFloatNumber, Eigen::Dynamic, 1> VectorXn;
90
91class CIccEigenMatrixSolver : public IIccMatrixSolver
92{
93public:
94 CIccEigenMatrixSolver() {}
95
96 /**
97 ****************************************************************************
98 * Member Function: Solve
99 *
100 * Purpose: Solve for x in the matrix/vector equation y=Mx
101 *
102 * Parameters:
103 * -dMatrix is a matrix (M) with nRows x nCols entries in RowOrder
104 * -dYVector is a column vector (y) with nRows entries
105 * -dXVecotr is a column vector (x) with nCols entries
106 *
107 * Return:
108 * true if solution was found or false if solution not possible.
109 *****************************************************************************
110 */
111 virtual bool Solve(icFloatNumber *dXVector, const icFloatNumber *dMatrix, const icFloatNumber *dYVector, icUInt16Number nRows, icUInt16Number nCols)
112 {
113 if (nRows==3 && nCols==3) {
114 icFloatNumber mtx[9];
115 memcpy(mtx, dMatrix, 9*sizeof(icFloatNumber));
116 bool bInvertible = icMatrixInvert3x3(mtx);
117 if (bInvertible)
118 icVectorApplyMatrix3x3(dXVector, mtx, dYVector);
119 else
120 memset(dXVector, 0, nCols*sizeof(icFloatNumber));
121
122 return bInvertible;
123 }
124
125 VectorXn x;
126 VectorXn y = Eigen::Map<VectorXn>((icFloatNumber*)dYVector, nRows);
127 MatrixXn A = Eigen::Map<MatrixXn>((icFloatNumber*)dMatrix, nRows, nCols);
128
129 x=solve(A,y);
130
131 Eigen::Map<VectorXn>(dXVector, nCols) = x;
132
133 return true;
134 }
135};
136
137CIccEigenMatrixSolver g_EigenSolver;
138
139//Define the global g_pIccMatrixSolver variable pointer
141
142#else
143
145{
146public:
148
149 /**
150 ****************************************************************************
151 * Member Function: Solve
152 *
153 * Purpose: Solve for x in the matrix/vector equation y=Mx when M is 3x3 matrix
154 * Otherwise return false.
155 *
156 * Parameters:
157 * -dMatrix is a matrix (M) with nRows x nCols entries in RowOrder
158 * -dYVector is a column vector (y) with nRows entries
159 * -dXVecotr is a column vector (x) with nCols entries
160 *
161 * Return:
162 * true if solution was found or false if solution not possible/supported.
163 *****************************************************************************
164 */
165 virtual bool Solve(icFloatNumber *dXVector, const icFloatNumber *dMatrix, const icFloatNumber *dYVector, icUInt16Number nRows, icUInt16Number nCols)
166 {
167 if (nRows==3 && nCols==3) {
168 icFloatNumber mtx[9];
169 memcpy(mtx, dMatrix, 9*sizeof(icFloatNumber));
170 bool bInvertible = icMatrixInvert3x3(mtx);
171 if (bInvertible)
172 icVectorApplyMatrix3x3(dXVector, mtx, dYVector);
173 else
174 memset(dXVector, 0, nCols*sizeof(icFloatNumber));
175
176 return bInvertible;
177 }
178
179 return false;
180 }
181};
182
184
185//Define the global g_pIccMatrixSolver variable pointer
187
188#endif
189
190
191
192/**
193****************************************************************************
194* Name: IccSetMatrixSolver(IIccMatrixSolver *pSolver)
195*
196* Purpose:
197* Global function that can be used by a supporting application to
198* establish an implementation of a matrix solver object.
199*****************************************************************************
200*/
202{
203 g_pIccMatrixSolver = pIccMatrixSolver;
204}
205
206
207/**
208****************************************************************************
209* Name: IccGetDefaultMatrixSolver()
210*
211* Purpose:
212* Global function that can be used by a supporting application to
213* determine the default matrix solver object.
214*****************************************************************************
215*/
220
221//TODO implement IIccMatrixInverter in terms of Eigen library
222
224{
225public:
227
228 /**
229 ****************************************************************************
230 * Member Function: Invert
231 *
232 * Purpose: Solve for x in the matrix/vector equation y=Mx when M is 3x3 matrix
233 * Otherwise return false.
234 *
235 * Parameters:
236 * -dMatrix is a matrix (M) with nRows x nCols entries in RowOrder
237 * -nRows is number of row entries
238 * -nCols is number of column entries
239 *
240 * Return:
241 * true if matrix was inverted or false if not possible/supported.
242 *****************************************************************************
243 */
244 virtual bool Invert(icFloatNumber *dMatrix, icUInt16Number nRows, icUInt16Number nCols)
245 {
246 if (nRows == 3 && nCols == 3) {
247 bool bInvertible = icMatrixInvert3x3(dMatrix);
248
249 return bInvertible;
250 }
251
252 return false;
253 }
254};
255
257
258//Define the global g_pIccMatrixSolver variable pointer
260
261
262
263/**
264****************************************************************************
265* Name: IccSetMatrixInverter(IIccMatrixInverter *pInverter)
266*
267* Purpose:
268* Global function that can be used by a supporting application to
269* establish an implementation of a matrix inverter object.
270*****************************************************************************
271*/
273{
274 g_pIccMatrixInverter = pIccMatrixInverter;
275}
276
277
278/**
279****************************************************************************
280* Name: IccGetDefaultMatrixInverter()
281*
282* Purpose:
283* Global function that can be used by a supporting application to
284* determine the default matrix inverter object.
285*****************************************************************************
286*/
float icFloatNumber
All floating point operations/variables in IccProfLib use the icFloatNumber data type.
Definition IccDefs.h:100
#define ICCPROFLIB_API
IIccMatrixInverter * g_pIccMatrixInverter
Global Variable: g_pIccMatrixInverter.
Definition IccSolve.cpp:259
IIccMatrixInverter * IccGetDefaultMatrixInverter()
Name: IccGetDefaultMatrixInverter()
Definition IccSolve.cpp:287
CIccSimpleMatrixInverter g_SimpleInverter
Definition IccSolve.cpp:256
void IccSetMatrixInverter(IIccMatrixInverter *pIccMatrixInverter)
Name: IccSetMatrixInverter(IIccMatrixInverter *pInverter)
Definition IccSolve.cpp:272
IIccMatrixSolver * g_pIccMatrixSolver
Global Variable: g_pIccMatrixSolver.
Definition IccSolve.cpp:186
IIccMatrixSolver * IccGetDefaultMatrixSolver()
Name: IccGetDefaultMatrixSolver()
Definition IccSolve.cpp:216
CIccSimpleMatrixSolver g_SimpleSolver
Definition IccSolve.cpp:183
void IccSetMatrixSolver(IIccMatrixSolver *pIccMatrixSolver)
Name: IccSetMatrixSolver(IIccMatrixSolver *pSolver)
Definition IccSolve.cpp:201
File: IccSolve.h.
bool icMatrixInvert3x3(icFloatNumber *M)
Name: icMatrixInvert3x3.
Definition IccUtil.cpp:391
void icVectorApplyMatrix3x3(icFloatNumber *result, const icFloatNumber *m, const icFloatNumber *v)
Name: icVectorApplyMatrix3x3.
Definition IccUtil.cpp:502
File: IccUtil.h.
virtual bool Invert(icFloatNumber *dMatrix, icUInt16Number nRows, icUInt16Number nCols)
Member Function: Invert.
Definition IccSolve.cpp:244
virtual bool Solve(icFloatNumber *dXVector, const icFloatNumber *dMatrix, const icFloatNumber *dYVector, icUInt16Number nRows, icUInt16Number nCols)
Member Function: Solve.
Definition IccSolve.cpp:165
Structure: IIccMatrixInverter.
Definition IccSolve.h:149
Structure: IIccMatrixSolver.
Definition IccSolve.h:86
virtual bool Solve(icFloatNumber *dXVector, const icFloatNumber *dMatrix, const icFloatNumber *dYVector, icUInt16Number nRows, icUInt16Number nCols)=0
Member Function: Solve.
unsigned short icUInt16Number