2017-08-07 1 views
1

Je peux écrire en fonction Matlab ainsi:Résolution d'un système non linéaire des équations Julia

function res=resid(theta,alpha,beta); 
RHS=[]; 
LHS=[]; 
RHS= theta-alpha; 
LHS= theta*beta; 
res = (LHS-RHS); 

Nous fixons les paramètres, appelez la fonction:

alpha=0.3;beta=0.95; 
a01=[1.0;1.0]; 
th=fsolve('resid',a01,[],alpha,beta) 

Ce sera de retour [6.0 6.0]. Est-ce que l'option "[]" signale à fsolve que l'entrée est un vecteur?

Quoi qu'il en soit, comment puis-je implémenter cela dans Julia en utilisant un NLsolve, Optim ou JuMP? Le problème original a plus de 10 variables, donc je préférerais une approche vectorielle.

Je peux mettre en œuvre la fonction de Julia:

h! =function (theta) 
RHS=[]; 
LHS=[]; 
RHS= theta-alpha; 
LHS= theta*beta; 
res= (LHS-RHS); 
return res; 
end 

Mais simplement en utilisant NLsolve:

a01 = [1.0;1.0]; 
res = nlsolve(h!,a01) 

Retours:

MethodError: no method matching (::##17#18)(::Array{Float64,1}, ::Array{Float64,1}) 
Closest candidates are: 
    #17(::Any) at In[23]:3 

Si j'utilise alternativement Optim, je reçois:

using Optim 
optimize(h!, a01) 

qui retourne:

MethodError: Cannot `convert` an object of type Array{Float64,1} to an object of type Float64 
This may have arisen from a call to the constructor Float64(...), 
since type constructors fall back to convert methods. 

Merci pour vos suggestions!

+0

Pourriez-vous indiquer quelles parties d'e.b. la documentation de NLsolve que vous avez examinée, et qu'est-ce qui vous cause en particulier des problèmes? –

+1

Il y a une mise à jour! – pp11

+1

Avez-vous regardé la documentation NLsolve.jl? Ce n'est pas comme ça que vous définissez la fonction. Si votre fonction n'est pas en place, vous utilisez 'nlsolve (not_in_place (f), initial_x)'. Mais pourquoi ne pas simplement utiliser la version inplace de la documentation? 'fonction f! (x, fvec)' premier vecteur est l'entrée seconde est sortie? –

Répondre

1

Suite à la suggestion de Chris Rackauckas, la solution serait de garder la définition de h:

h =function (theta) 
RHS=[]; 
LHS=[]; 
RHS= theta-alpha; 
LHS= theta*beta; 
res= (LHS-RHS); 
return res; 
end 

et à utiliser not_in_place:

a01 = [1.0;1.0]; 
solve = nlsolve(not_in_place(h),a01) 

De retour d'une solution:

Results of Nonlinear Solver Algorithm 
* Algorithm: Trust-region with dogleg and autoscaling 
* Starting Point: [1.0,1.0] 
* Zero: [6.0,6.0] 
* Inf-norm of residuals: 0.000000 
* Iterations: 3 
* Convergence: true 
    * |x - x'| < 0.0e+00: false 
    * |f(x)| < 1.0e-08: true 
* Function Calls (f): 4 
* Jacobian Calls (df/dx): 4 

Merci!

+1

Par convention, vous ne devriez pas appeler la fonction 'h!' Si ce n'est pas une fonction de mutation. Voir [cette page dans les documents] (https://docs.julialang.org/fr/latest/manual/style-guide/#Append-!-to-names-of-functions-that-modify-their-arguments- 1). En outre, vous devez marquer cela comme la solution afin que les autres utilisateurs SO puissent voir que cela a été résolu. –

+0

Ok! Mais puisque j'ai écrit une réponse moi-même, je serai capable de le marquer dans 48 heures. Mais je vais le faire ... – pp11