分享
 
 
 

MATLAB结合C/C++建立独立的应用程序(2)

王朝c/c++·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

2.2 Tool Box函数的调用

Tool Box函数定义在以.m为扩展名的文件中,如regress.m就是一个工具箱函数,用来计算多元线性回归,函数体如下:

function [b,bint,r,rint,stats] = regress(y,X,alpha)

if nargin < 2,

error('REGRESS requires at least two input arguments.');

end

if nargin == 2,

alpha = 0.05;

end

% Check that matrix (X) and left hand side (y) have compatible dimensions

[n,p] = size(X);

[n1,collhs] = size(y);

if n ~= n1,

error('The number of rows in Y must equal the number of rows in X.');

end

if collhs ~= 1,

error('Y must be a vector, not a matrix');

end

% Remove missing values, if any

wasnan = (isnan(y) | any(isnan(X),2));

if (any(wasnan))

y(wasnan) = [];

X(wasnan,:) = [];

n = length(y);

end

% Find the least squares solution.

[Q, R]=qr(X,0);

b = R\(Q'*y);

% Find a confidence interval for each component of x

% Draper and Smith, equation 2.6.15, page 94

RI = R\eye(p);

xdiag=sqrt(sum((RI .* RI)',1))';

nu = n-p; % Residual degrees of freedom

yhat = X*b; % Predicted responses at each data point.

r = y-yhat; % Residuals.

if nu ~= 0

rmse = norm(r)/sqrt(nu); % Root mean square error.

else

rmse = Inf;

end

s2 = rmse^2; % Estimator of error variance.

tval = tinv((1-alpha/2),nu);

bint = [b-tval*xdiag*rmse, b+tval*xdiag*rmse];

% Calculate R-squared.

if nargout==5,

RSS = norm(yhat-mean(y))^2; % Regression sum of squares.

TSS = norm(y-mean(y))^2; % Total sum of squares.

r2 = RSS/TSS; % R-square statistic.

if (p>1)

F = (RSS/(p-1))/s2; % F statistic for regression

else

F = NaN;

end

prob = 1 - fcdf(F,p-1,nu); % Significance probability for regression

stats = [r2 F prob];

% All that requires a constant. Do we have one?

if (~any(all(X==1)))

% Apparently not, but look for an implied constant.

b0 = R\(Q'*ones(n,1));

if (sum(abs(1-X*b0))>n*sqrt(eps))

warning(sprintf(['R-square is not well defined unless X has' ...

' a column of ones.\nType "help regress" for' ...

' more information.']));

end

end

end

% Find the standard errors of the residuals.

% Get the diagonal elements of the "Hat" matrix.

% Calculate the variance estimate obtained by removing each case (i.e. sigmai)

% see Chatterjee and Hadi p. 380 equation 14.

T = X*RI;

hatdiag=sum((T .* T)',1)';

ok = ((1-hatdiag) > sqrt(eps));

hatdiag(~ok) = 1;

if nu < 1,

ser=rmse*ones(length(y),1);

elseif nu > 1

denom = (nu-1) .* (1-hatdiag);

sigmai = zeros(length(denom),1);

sigmai(ok) = sqrt((nu*s2/(nu-1)) - (r(ok) .^2 ./ denom(ok)));

ser = sqrt(1-hatdiag) .* sigmai;

ser(~ok) = Inf;

elseif nu == 1

ser = sqrt(1-hatdiag) .* rmse;

ser(~ok) = Inf;

end

% Create confidence intervals for residuals.

Z=[(r-tval*ser) (r+tval*ser)]';

rint=Z';

% Restore NaN so inputs and outputs conform

if (nargout>2 & any(wasnan))

tmp = ones(size(wasnan));

tmp(:) = NaN;

tmp(~wasnan) = r;

r = tmp;

end

if (nargout>3 & any(wasnan))

tmp = ones(length(wasnan),2);

tmp(:) = NaN;

tmp(~wasnan,:) = rint;

rint = tmp;

end

由于这个函数是由MATLAB专有的语言写成,而并非C语言,所以我们并不能直接使用在我们的程序中。不过没关系MATLAB为我们提供了强大的工具mcc.exe,它能够将.m文件中的函数翻译成我们需要的C/C++程序,这个功能令我们的开发事半功倍。

下面具体阐述一下mcc的使用方法。

1.设置一个有效的C编译器,这里面使用MATLAB自带的编译器Lcc C version 2.4。

开启MATLAB环境,在Command window里面输入

>> mbuild –setup

Please choose your compiler for building standalone MATLAB applications:

Would you like mbuild to locate installed compilers [y]/n? y

Select a compiler:

[1] Lcc C version 2.4 in D:\MATLAB\sys\lcc

[2] Microsoft Visual C/C++ version 6.0 in C:\Program Files\Microsoft Visual Studio

[0] None

Compiler: 1

Please verify your choices:

Compiler: Lcc C 2.4

Location: D:\MATLAB\sys\lcc

Are these correct?([y]/n): y

The default options file:

"C:\Documents and Settings\Administrator\Application Data\MathWorks\MATLAB\R12\compopts.bat"

is being updated from D:\MATLAB\BIN\WIN32\mbuildopts\lcccompp.bat...

现在我们已经将位于D:\MATLAB\sys\lcc的一个c/c++编译器设为我们要使用的编译器。

2.现在可以使用mcc来生成C文件了,这里我们使用regress.m这个文件作为例子,生成相应的c语言文件。在Command Window 里面输入

>> mcc -m regress

执行完毕后,你打开<matlab>\work目录,你会发现目录中有了我们需要的文件regress.h和regress.c以及很多其他C文件和C的头文件,这些其他文件都是regress函数里面用到的其它工具箱函数所对应的C语言文件,难以想象mcc为我们做了多么繁琐而复杂的事情呀!

在Command Window 里面输入

>> mcc –p regress

执行完毕后,就能在work目录下生成对应的CPP文件。

3.新建一个控制台程序,主程序代码如下:

#pragma hdrstop

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include "libmatlb.h"

#include "libmmfile.h"

#include "regress.h"

#include "fcdf.h"

#include "tinv.h"

#include "chi2cdf.h"

#include "distchck.h"

#include "betainv.h"

#include "norminv.h"

#include "gamcdf.h"

#include "betacdf.h"

#include "betapdf.h"

#pragma argsused

static _mexInitTermTableEntry init_term_table[11]

= { { libmmfileInitialize, libmmfileTerminate },

{ InitializeModule_regress, TerminateModule_regress },

{ InitializeModule_fcdf, TerminateModule_fcdf },

{ InitializeModule_tinv, TerminateModule_tinv },

{ InitializeModule_chi2cdf, TerminateModule_chi2cdf },

{ InitializeModule_distchck, TerminateModule_distchck },

{ InitializeModule_betainv, TerminateModule_betainv },

{ InitializeModule_norminv, TerminateModule_norminv },

{ InitializeModule_gamcdf, TerminateModule_gamcdf },

{ InitializeModule_betacdf, TerminateModule_betacdf },

{ InitializeModule_betapdf, TerminateModule_betapdf } };

static double buf1[] = { 1, 2 ,3,3,2,1,3,3,4};

static double buf2[] = { 3, 4 ,4 };

int main(int argc, const char * * argv) {

mxArray *x = NULL;

mxArray *y = NULL;

mxArray *alpha = NULL;

mxArray *bint = NULL, *r = NULL, *rint = NULL;

mxArray *status = NULL,*b=NULL;

/* Enable automated memory management */

mlfEnterNewContext(0, 0);

/* Create the matrices and assign data to them */

mlfAssign(&x, mlfDoubleMatrix(3, 3, buf1, NULL));

mlfAssign(&y, mlfDoubleMatrix(3, 1, buf2, NULL));

mlfAssign(&alpha,mlfScalar(1));

/* Print the matrices */

mlfPrintMatrix(x);

mlfPrintMatrix(y);

int i;

for(i=0;i<sizeof(init_term_table)/sizeof(_mexInitTermTableEntry);i++)

{

init_term_table[i].initialize();

}

b=mlfRegress(&bint,&r,&rint,&status,y,x,alpha);

//b=mlfRegress(NULL,NULL,NULL,NULL,mat0,mat1,alpha);

mlfPrintMatrix(b);

mlfPrintMatrix(bint);

mlfPrintMatrix(r);

mlfPrintMatrix(rint);

mlfPrintMatrix(status);

/* Free the matrices */

mxDestroyArray(x);

mxDestroyArray(y);

for(i=0;i<sizeof(init_term_table)/sizeof(_mexInitTermTableEntry);i++)

{

init_term_table[i].terminate();

}

/* Disable automated memory management */

mlfRestorePreviousContext(0, 0);

return(EXIT_SUCCESS);

}

2.3 调用Tool Box函数的另一个可供选择的方法

2.2节提出的调用ToolBox函数的方法比较繁杂,因为MATLAT编译器会为你生成一大堆C/C++源代码文件和头文件,对这些源代码的维护也就比较复杂,随着系统的不断发展,程序员对这些MATLAB生成的源代码的维护将会变得极其困难,在此提出另一个可供选择的方法:将ToolBox函数编译成动态链接库。对程序员来说,相比之下二进制级别的重用要比源代码级的重用更易于维护和使用。

那么到底怎么把ToolBox函数编译成动态链接库呢?庆幸的是MATLAT编译器能为我们来完成这项任务!下面我来讲述一下。

首先正确设置MCC(对MCC的使用见2.2章)。然后输入如下命令:

mcc -t -W lib:test -T link:lib betaln erf erfcore realmax betacdf betapdf erfinv gammaln betacore erfc gammainc gamcdf distchck betainv norminv betainc chi2cdf tinv mean fcdf regress

执行这条命令就会生成一个test.dll、test.lib以及dll中导出函数的声明头文件。有了这些文件就可以轻松调用DLL中的函数了。

注意

①这条命令的主要目的是要生成regress这个函数,但是由于计算regress时需要调用到那些子函数如betaln,erf,erfcore等等,所以才会写这么一大串,如果仅仅执行

mcc -t -W lib:test -T link:lib regress

MATLAT编译器将会给出错误信息。

②编译器生成的LIB文件是coff格式的,如果你要在bcb中静态加载DLL,则需要把coff格式转变成omf格式。可以是用coff2omf.exe这个工具,或者索性使用IMPLIB.exe重新生成一个LIB文件。关于这两个工具的使用方法可以参考它们的帮助。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有